商场促销 |
难度级别:A; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B |
试题描述
|
商场购物现金结算促销,单张购物小票满300元全款九折,满500元全款八折,满1000元立减300元。现输入用户单张小票购物的金额 x(0<x<2000),输出用户的应付款数,用到的变量都使用double类型。
|
输入
|
一个数,表示单张购物小票的金额。
|
输出
|
一个数,表示客户实际应付款的数额。
|
输入示例
|
350
|
输出示例
|
315
|
分析
分支,不多说。
代码
#include<bits/stdc++.h>
using namespace std;
double a;
int main()
{
cin>>a;
if(a<300) cout<<a;//不够300元不打折。
else if(a<500) cout<<a*0.9;//满300元打九折。
else if(a<1000) cout<<a*0.8;//满500元打八折。
else if(a>1000) cout<<a-300;//满1000元减300元。
return 0;
}

23种设计模式之状态模式和策略模式的区别
概述
在行为类设计模式中,状态模式和策略模式是亲兄弟,两者非常相似,我们先看看两者的通用类图,把两者放在一起比较一下

状态模式
状态模式
状态模式的类图与策略模式一模一样,区别在于它们的意图。策略模式会控制对象使用什么策略,而状态模式会自动改变状态。
例如网购的商品订单,处于不同的状态,但是是针对同一订单的不同的状态。同一处理方法,状态切换了做的事情就不同。

策略模式
策略模式
例如聚合支付平台,有支付宝、微信支付、银联支付等,可以使用不同的支付策略。

区别
1、状态模式重点在各状态之间的切换,从而做不同的事情;而策略模式更侧重于根据具体情况选择策略,并不涉及切换。
2、状态模式不同状态下做的事情不同,而策略模式做的都是同一件事。例如,聚合支付平台,有支付宝、微信支付、银联支付,虽然策略不同,但最终做的事情都是支付,也就是说他们之间是可替换的。反观状态模式,各个状态的同一方法做的是不同的事,不能互相替换。
3、状态模式封装了对象的状态,而策略模式封装算法或策略。因为状态是跟对象密切相关的,它不能被重用;而策略模式通过从Context中分离出策略或算法,我们可以重用它们。
4、在状态模式中,每个状态通过持有Context的引用,来实现状态转移;但是每个策略都不持有Context的引用,它们只是被Context使用。
5、状态模式将各个状态所对应的操作分离开来,即对于不同的状态,由不同的子类实现具体操作,不同状态的切换由子类实现,当发现传入参数不是自己这个状态所对应的参数,则自己给Context类切换状态;这种转换是"自动","无意识"的。状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。而策略模式是直接依赖注入到Context类的参数进行策略选择,不存在切换状态的操作。
6、策略模式的客户端必须对所有的策略类相当了解,明确当前场景下各种策略的利弊,权衡在当前场景下应该使用哪种策略,也就是是说策略类对客户端是暴露的,策略是外界给的,策略怎么变,是调用者考虑的事情,系统只是根据所给的策略做事情。
状态模式依赖于其状态的变化时其内部的行为发生变化,将动作委托到代表当前状态的对象,对外表现为类发生了变化。状态是系统自身的固有的,由系统本身控制,调用者不能直接指定或改变系统的状态转移。
总结
状态模式与策略模式很相似,确切的说状态模式包含策略模式。
策略模式封装的是行为,而状态模式封装的是变化。尽管这么说,但事实上策略模式与状态模式在很多情况下都是可以互相转化的,具体应该使用何种模式,就要从上面的两个方面尽心分析,能够看得出明显状态变化的,当热要用状态模式;如果只是选择一个合适的具体执行方案,那么显然策略模式更为适合,毕竟状态模式由于牵涉到状态的变化和转移方向,是要比策略模式略微复杂的,这里的复杂并不是指代码难以理解,而是从设计模式的角度来说明类的结构。
更多更好看这里。。。

C++------ 单例模式,模版模式,原型模式,策略模式和适配器模式
1. 单例模式
单例模式是一种常用的软件模式。在它的核心结构中只有一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类只有一个实例。
Ps:
1)单例类只能有一个实例。
2)单例类必须自己创建自己的唯一实例。
3)单例类必须给所有其他对象提供这一实例。
4)单例类的构造方法是私有的
代码如下:
1 #include <iostream>
2 using namespace std;
3 class Single
4 {
5 public:
6 static Single* CreateSingle()
7 {
8 if(ss == NULL)
9 {
10 ss = new Single();
11 }
12 return ss;
13 }
14 private:
15 static Single* ss;
16 Single()
17 {
18 cout << "Single()" << endl;
19 }
20 };
21 Single* Single::ss = NULL;
22 int main()
23 {
24 Single* ss = Single::CreateSingle();
25 }
2. 模版模式
模版模式是一个抽象类公开定义了执行它的方法的方式 / 模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。
例如:
我门填写简历,每个人简历不同,但填写顺序一致
代码如下:
#include <iostream>
using namespace std;
class Info
{
public:
void TemplateMethod()
{
first();
second();
third();
}
private:
virtual void first() = 0;
virtual void second() = 0;
virtual void third() = 0;
};
class Info1:public Info
{
public:
private:
void first()
{
cout << "first" << endl;
}
void second()
{
cout << "second" << endl;
}
void third()
{
cout << "third" << endl;
}
};
int main()
{
Info1 man;
man.TemplateMethod();
}
3. 原型模式
是指指定创建对象的类型,并且通过拷贝这些原型创建新的对象。通过拷贝构造函数实现。
例如:
修改简历,只需要修改一份,然后通过打印机设备复印多份即可
代码如下:
1 #include <iostream>
2 using namespace std;
3 class Resume
4 {
5 public:
6 Resume(){}
7 virtual ~Resume(){}
8 virtual Resume* Clone() = 0;
9 };
10 class ResumeA:public Resume
11 {
12 public:
13 ResumeA(){}
14 ResumeA(ResumeA& rr)
15 {
16 cout << "Copy ResumeA(ResumeA&)" << endl;
17 }
18 Resume* Clone()
19 {
20 return new ResumeA(*this);
21 }
22 ~ResumeA(){}
23 };
24
25 int main()
26 {
27 ResumeA aa;
28 Resume* a = aa.Clone();
29 }
4. 策略模式
策略模式是指定义一系列的算法进行分别封装,它们可以相互替换。本模式可以使算法独立于使用它的客户而变化。对外的接口是一样的,完成的功能是一样的,只是各自实现的上有差异。
例如:
Cache 的替换算法;cache 高速缓冲存储器一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问。
代码如下:
1 #include <iostream>
2 using namespace std;
3 class ReplaceAlgorithm
4 {
5 public:
6 virtual void Replace() = 0;
7 };
8 class FIFO_ReplaceAlgorithm:public ReplaceAlgorithm
9 {
10 public:
11 void Replace()
12 {
13 cout << "FIFO_ReplaceAlgorithm" << endl;
14 }
15 };
16 class LRU_ReplaceAlgorithm:public ReplaceAlgorithm
17 {
18 public:
19 void Replace()
20 {
21 cout << "LRU_ReplaceAlgorithm" << endl;
22 }
23 };
24
25 class Random_ReplaceAlgorithm:public ReplaceAlgorithm
26 {
27 public:
28 void Replace()
29 {
30 cout << "Random_ReplaceAlgorithm" << endl;
31 }
32 };
Cache 有三种方法使用第一种通过构造函数参数获取算法类对象
1 class Cache
2 {
3 public:
4 Cache(ReplaceAlgorithm* ra)
5 {
6 mm = ra;
7 }
8 ~Cache(){delete mm;}
9 void Replace(){ mm->Replace();}
10 private:
11 ReplaceAlgorithm* mm;
12 };
13
14 int main()
15 {
16 Cache mm(new Random_ReplaceAlgorithm());
17 mm.Replace();
18 }
第二种,通过算法名的标签创建算法类对象
1 enum RA {LRU,FIFO,RANDOM};
2 class Cache
3 {
4 public:
5 Cache(enum RA ss)
6 {
7 if(ss == LRU)
8 mm = new LRU_ReplaceAlgorithm();
9 else if(ss == FIFO)
10 mm = new FIFO_ReplaceAlgorithm();
11 else
12 mm = new Random_ReplaceAlgorithm();
13 }
14 ~Cache(){delete mm;}
15 void Replace(){ mm->Replace();}
16 private:
17 ReplaceAlgorithm* mm;
18 };
19 int main()
20 {
21 Cache mm(LRU);
22 mm.Replace();
23 }
第三种类模板实现
1 template <typename RA>
2 class Cache
3 {
4 public:
5 Cache(){}
6 ~Cache(){}
7 void Replace(){ mm.Replace();}
8 private:
9 RA mm;
10 };
11 int main()
12 {
13 Cache<FIFO_ReplaceAlgorithm> mm;
14 mm.Replace();
15 }
5. 适配器模式
是指将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能在一起工作的哪些类可以一起工作
例如:
读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。
有一个类需要实现数据插入和删除,现在有一个数组类里面有插入和删除的方法,通过适配器实现调用数组类的方法。
代码如下:
1 #include <iostream>
2 using namespace std;
3 class Sequence
4 {
5 public:
6 Sequence(){};
7 virtual void push(int num) = 0;
8 virtual void pop() = 0;
9 };
10
11 /*
12 * 默认数组大小是10;
13 * 插入,如果数组已满,重新申请size+10的空间
14 * 删除,如果数组为空,删除返回-1;
15 * 不为空,返回当前删除的值;
16 * 获取指定位置的数值,如果指定位置超出当前的数据长度,返回-1,并显示数据长度
17 * 在当前的数据长度,返回指定位置的数值
18 * 设置指定位置的数值,如果指定位置超出当前空间的大小,显示空间大小
19 *
20 */
21 class Array
22 {
23 public:
24 Array()
25 {
26 size = 10;
27 len = 0;
28 p = new int[size];
29 *p = 0;
30 }
31 Array(int len)
32 {
33
34 p = new int[len];
35 this->len = 0;
36 this->size = len;
37 }
38 Array(int len, int data)
39 {
40 this->size = len;
41 this->len = len-1;
42 p = new int[size];
43 for(int i=0; i<size; i++)
44 {
45 *(p+i) = data;
46 }
47 //cout << "Arrat(int,int)" << endl;
48 }
49 int get(int index)
50 {
51 if(index > len)
52 {
53 cout << "超出范围" << endl;
54 cout << "当前最后数据长度:"<<len;
55 return -1;
56 }
57 return p[index];
58 }
59 void set(int index, int data)
60 {
61 if(index > size)
62 {
63 cout << "超出范围" << endl;
64 cout << "当前空间大小为:" << size << endl;
65 return;
66 }
67 p[index] = data;
68 }
69 void push_back(int data)
70 {
71 if(isFull() == true)
72 {
73 //空间已满,重新申请内存(为避免多次申请内存,每次申请size+10的空间),释放原来内存
74 getNewKongjian();
75 }
76 len += 1;
77 p[len] = data;
78 cout << "push_back()" << endl;
79 }
80 void push_front(int data)
81 {
82 if(isFull() == true)
83 {
84 getNewKongjian();
85 }
86 for(int i = len;i >= 0; i--)
87 {
88 p[i+1] = p[i];
89 }
90 len += 1;
91 p[0] = data;
92 cout << "push_fron" << endl;
93 }
94 int pop_back()
95 {
96 if(isEmpty() == true)
97 {
98 cout << "没有数据可以删除,当墙空间为空" << endl;
99 cout << "当前空间大小是:" << this->size << endl;
100 return -1;
101 }
102 int temp = p[len];
103 len -= 1;
104
105 cout << "pop_back()" << endl;
106 return temp;
107 }
108 int pop_front()
109 {
110 if(isEmpty() == true)
111 {
112 cout << "没有数据可以删除,当前空间为空" << endl;
113 cout << "当前空间大小是:" << this->size << endl;
114 return -1;
115 }
116 int temp = p[0];
117 for(int i = 0; i <= len; i++)
118 {
119 p[i] = p[i+1];
120 }
121 p[len] = 0;
122 len -= 1;
123 cout << "pop_front()" << endl;
124 return temp;
125 }
126 ~Array()
127 {
128 delete[] p;
129 p = NULL;
130 len = 0;
131 cout << "~Array" << endl;
132 }
133 void Show()
134 {
135 for(int i = 0; i < len; i++)
136 cout << p[i] <<" ";
137 cout << endl;
138 }
139
140 private:
141 int * p;
142 int len;
143 int size;
144 bool isFull()
145 {
146 if(len == size-1)
147 return true;
148 else
149 return false;
150 }
151 bool isEmpty()
152 {
153 if(len == -1)
154 return true;
155 else
156 return false;
157 }
158 void getNewKongjian()
159 {
160
161 size += 10;
162 int* temp = new int[size];
163 //将原来数据拷贝到新内存中
164 for(int i=0;i<=len;i++)
165 {
166 temp[i] = p[i];
167 }
168 delete[] p;
169 p = temp;
170 }
171 };
172 class Queue:public Sequence
173 {
174 public:
175 Queue():a(){}
176 Queue(int len):a(len){}
177 Queue(int len, int data):a(len,data){}
178 ~Queue()
179 {
180 cout << "~Queue" << endl;
181 }
182 void push(int num)
183 {
184 a.push_back(num);
185 }
186 void pop()
187 {
188 cout << a.pop_back() << endl;
189 }
190 private:
191 Array a;
192 };
193
194 int main()
195 {
196 {
197 Sequence* da = new Queue(2,3);
198 da->push(1);
199 da->pop();
200 da->pop();
201 da->pop();
202 da->pop();
203 delete da;
204 }
205 }

golang 策略模式之排序算法策略
起源
最近在学设计模式,这个东西学起来,总是模模糊糊,看起来懂,又不知该应用到何处,咬着牙学完了之后,准备学习算法,写了两个简单的排序算法,突然灵光一闪,如果我想用不用的算法去排序的时候,完全可以用策略模式,正好学以致用
示例
我先设计了一个排序接口
type sortAlgo interface {
sort([]int)
}
然后,我写了两个算法,一个是冒泡排序,一个是简单选择排序,都实现了这个接口
type bubbleSort struct {
}
func (b *bubbleSort) sort(data []int) {
n := len(data)
for i:=0; i<n-1; i++ {
for j:=n-1; j>i; j-- {
if data[j-1] > data[j] {
tmp := data[j-1]
data[j-1] = data[j]
data[j] = tmp
}
} }}
type simpleSelectSort struct {
}
func (s *simpleSelectSort) sort(data []int) {
n := len(data)
for i:=0; i<n; i++ {
minIndex := i
for j:=i+1; j<n; j++ {
if data[j] < data[minIndex] {
minIndex = j
}
} if minIndex != i {
tmp := data[minIndex]
data[minIndex] = data[i]
data[i] = tmp
}
}}
最后,我构建一个策略模式,可以通过设计,决定使用哪一个算法
type sortStrategy struct {
data []int
sortAlgo
}
func (s *sortStrategy) setAlgo(sa sortAlgo) {
s.sortAlgo = sa
}
func (s *sortStrategy) setData(data []int) {
s.data = data
}
func (s *sortStrategy) run() {
s.sortAlgo.sort(s.data)
}
总结
说实话,这么写有点Java了,但是我看的设计模式的书,就是基于Java的,先学习思想嘛
我脑海中,现在还蹦出来另一个思路,排序时,接收一个排序方法,再调用
type sortFunc func([]int)
这样是不是更gopher了呢
今天关于商场促销 策略模式和商场促销 策略模式有哪些的介绍到此结束,谢谢您的阅读,有关0036-商场促销、23种设计模式之状态模式和策略模式的区别、C++------ 单例模式,模版模式,原型模式,策略模式和适配器模式、golang 策略模式之排序算法策略等更多相关知识的信息可以在本站进行查询。