中缀表达式转换为后缀表达式
在表达式计算中,第一要做的就是讲中缀表达式转换成后缀表达式
所采用的方式是,扫描中缀表达式,检测每个中缀表达式的元素
如果是操作数,则将其加入到输出的后缀表达式中
如果是操作符,需要对其分析,设定一个操作符栈,
·如果一开始操作符栈为空,则将该操作符压栈
·这里涉及左括号的两个优先级,即栈外优先级和栈内优先级,如果左括号在栈外,则其优先级最高,直接将其压入到操作符栈中,如果左括号在栈内,则其优先级很低,只有在碰到右括号的时候才会弹栈,遇到其他运算符时,直接当其他运算符压栈。
·这里涉及操作符优先级问题,+ - * / % 这里的优先级相对于压操作符栈的优先级。即检测当前操作符与栈顶的操作符优先级,如果当前操作符优先级高于栈顶操作符优先级,需要将当前操作符压栈,如果当前操作符优先级小于或等于栈顶操作符优先级,则将栈顶操作符出栈,然后再次检测下一个栈顶操作符的优先级与当前操作符优先级关系。
·对于有左括号和右括号的情况,需要对其做特殊分析。左括号会被压入栈中,右括号不会。如果当前元素时左括号,由于其栈外优先级最高,可以直接将其压入栈中,如果栈顶优先级是左括号,并且当前操作符是一般操作符,则直接将当前操作符压入栈中,如果当前操作符是右括号,则直接将栈顶的左括号出栈。
·中缀表达式和后缀表达式的不同是操作符的相对位置存在变化,当然后缀表达式不会出现括号,也就是后缀表达式中隐式包含了操作符的优先级。另外中缀和后缀表达式中的操作数相对顺序是一致的,在转换的过程中,当当前中缀表达式中的元素时操作数时,直接将其添加到输出后缀表达式中就可以。
这里利用的栈是操作符栈
在计算后缀表达式的过程中,利用的栈是操作数栈
从中缀表达式转换为后缀表达式也是一遍扫描中缀表达式即可,当然中间涉及对操作符栈的操作。
修正:( ( 1 + 2 ) * 3 + ( 1 + 10 ) ) / 2 , ( ( ( 1 + 2 + 3 ) ) ) 的情形。要时刻考虑到括号的特殊性,左括号的栈内优先级和栈外优先级的区别。对于左括号和右括号的主动入栈和出栈以及其他操作符的相对于其入栈和出栈决策要考虑清楚。
实现:
1 #include <iostream>
2 #include <string>
3 #include <vector>
4 #include <stack>
5 #include <map>
6 using namespace std;
7
8 map<string, int> operatorPriors;
9
10 void getInfix(vector<string>& infix)
11 {
12 infix.clear();
13 string tmp;
14 while (cin >> tmp)
15 {
16 infix.push_back(tmp);
17 }
18 }
19
20 void init()
21 {
22 operatorPriors["+"] = 10;
23 operatorPriors["-"] = 10;
24 operatorPriors["*"] = 20;
25 operatorPriors["/"] = 20;
26 operatorPriors["%"] = 20;
27 operatorPriors["("] = 30;
28 operatorPriors[")"] = 0;
29 }
30
31 bool prior(const string& op1, const string& op2)
32 {
33 return operatorPriors[op1] > operatorPriors[op2];
34 }
35
36 bool isOperator(const string& s)
37 {
38 return operatorPriors.find(s) != operatorPriors.end();
39 }
40
41 void print(stack<string> operators)
42 {
43 while (!operators.empty())
44 {
45 cout << operators.top() << ' ';
46 operators.pop();
47 }
48 cout << endl;
49 }
50
51 const vector<string>& infixToPostfix(vector<string>& postfix, const vector<string>& infix)
52 {
53 postfix.clear();
54 stack<string> operators;
55 for (vector<string>::size_type i = 0; i != infix.size(); ++i)
56 {
57 if (isOperator(infix[i]))
58 {
59 if (operators.empty())
60 {
61 operators.push(infix[i]);
62 }
63 else if (operators.top() == "(" && infix[i] != ")" || prior(infix[i], operators.top()))
64 {
65 operators.push(infix[i]);
66 }
67 else
68 {
69 if (infix[i] == ")")
70 {
71 while (operators.top() != "(")
72 {
73 postfix.push_back(operators.top());
74 operators.pop();
75 }
76 operators.pop();
77 }
78 else
79 {
80 postfix.push_back(operators.top());
81 operators.pop();
82 while (!operators.empty() && !prior(infix[i], operators.top()) && operators.top() != "(")
83 {
84 postfix.push_back(operators.top());
85 operators.pop();
86 }
87
88 operators.push(infix[i]);
89 }
90 }
91 }
92 else
93 {
94 postfix.push_back(infix[i]);
95 }
96 }
97 while (!operators.empty())
98 {
99 postfix.push_back(operators.top());
100 operators.pop();
101 }
102 return postfix;
103 }
104
105 int main()
106 {
107 init();
108 vector<string> infix;
109 vector<string> postfix;
110 getInfix(infix);
111 infixToPostfix(postfix, infix);
112 for (vector<string>::size_type i = 0; i != postfix.size(); ++i)
113 {
114 cout << postfix[i] << ' ';
115 }
116 cout << endl;
117 return 0;
118 }
posted @
2011-06-29 01:07 unixfy 阅读(566) |
评论 (0) |
编辑 收藏
后缀表达式的计算
表达式运算过程中,需要先做中缀表达式到后缀表达式的转换。
这里现对后缀表达式求值进行解答。
对后缀表达式进行扫描,遇到操作数将操作数压栈,遇到运算符将操作数出栈,进行运算,将运算的结果压入到操作数栈中。
注意,对于双目运算符,在堆操作数栈出栈的时候要注意,后弹出的操作符为左边的操作符,不要弄反了。
之前的做法是错误的,把后缀表达式存在一个栈中,只对栈顶操作,对于 a b c + * 这种情况不成立。
实现如下:
1 #include <iostream>
2 #include <vector>
3 #include <string>
4 #include <stack>
5 #include <sstream>
6 #include <cstdlib>
7 using namespace std;
8
9 void getPost(vector<string>& post)
10 {
11 post.clear();
12 string tmp;
13 while (cin >> tmp)
14 {
15 post.push_back(tmp);
16 }
17 }
18
19 double stringToDouble(const string& s)
20 {
21 return (atof(s.c_str()));
22 }
23
24 double evalPost(const vector<string>& post)
25 {
26 stack<double> operands;
27 int a, b;
28 for (vector<string>::size_type i = 0; i != post.size(); ++i)
29 {
30 if (post[i] == "+")
31 {
32 b = operands.top();
33 operands.pop();
34 a = operands.top();
35 operands.pop();
36 operands.push(a + b);
37 }
38 else if (post[i] == "-")
39 {
40 b = operands.top();
41 operands.pop();
42 a = operands.top();
43 operands.pop();
44 operands.push(a - b);
45 }
46 else if (post[i] == "*")
47 {
48 b = operands.top();
49 operands.pop();
50 a = operands.top();
51 operands.pop();
52 operands.push(a * b);
53 }
54 else if (post[i] == "/")
55 {
56 b = operands.top();
57 operands.pop();
58 a = operands.top();
59 operands.pop();
60 operands.push(a / b);
61 }
62 else if (post[i] == "%")
63 {
64 b = operands.top();
65 operands.pop();
66 a =operands.top();
67 operands.pop();
68 operands.push(a - b);
69 }
70 else
71 {
72 // stringstream ss;
73 // ss << post[i];
74 // ss >> a;
75 operands.push(stringToDouble(post[i]));
76 }
77 }
78 return operands.top();
79 }
80
81 int main()
82 {
83 vector<string> post;
84 getPost(post);
85 cout << evalPost(post) << endl;
86 return 0;
87 }
posted @
2011-06-28 23:20 unixfy 阅读(683) |
评论 (0) |
编辑 收藏
继承层次中的输入输出运算符重载
class A
{
};
class B : public A
{
};
方案一
可对 A 进行重载输入输出运算符,然后也对 B 重载相应版本的输入输出运算符
方案二
只对 A 进行重载输入输出运算符,对 A 定义一个 virtual print 函数,在 B 中也对该 virtual 函数 override
在重载的输入输出运算符中调用 virtual print 函数
1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 class Complex
6 {
7 protected:
8 // private:
9 int nR;
10 int nI;
11 public:
12 Complex(int tmpR = -100, int tmpI = -100);
13 virtual void display();
14 virtual ostream& print(ostream& os) const;
15 friend ostream& operator << (ostream&, const Complex&);
16 };
17
18 class NameComplex : public Complex
19 {
20 private:
21 string strName;
22 public:
23 NameComplex(const string& = "abc", int = -100, int = -100);
24 virtual void display();
25 virtual ostream& print(ostream& os) const;
26 // friend ostream& operator << (ostream&, const NameComplex&);
27 };
28
29 Complex::Complex(int tmpR, int tmpI) : nR(tmpR), nI(tmpI) {}
30
31 void Complex::display()
32 {
33 cout << nR << endl;
34 cout << nI << endl;
35 }
36
37 ostream& Complex::print(ostream& os) const
38 {
39 os << nR << ' ' << nI;
40 return os;
41 }
42
43 /*
44 ostream& operator << (ostream& os, const Complex& rhs)
45 {
46 os << rhs.nR << ' ' << rhs.nI;
47 return os;
48 }
49 */
50
51 ostream& operator << (ostream& os, const Complex& rhs)
52 {
53 return rhs.print(os);
54 }
55
56 NameComplex::NameComplex(const string& str, int nR, int nI) : Complex(nR, nI), strName(str) {}
57
58 void NameComplex::display()
59 {
60 cout << strName << endl;
61 Complex::display();
62 }
63
64 /*
65 ostream& operator << (ostream& os, const NameComplex& rhs)
66 {
67 os << rhs.strName << ' ';
68 operator << (os, static_cast<Complex>(rhs));
69 return os;
70 }
71 */
72
73 ostream& NameComplex::print(ostream& os) const
74 {
75 os << strName << ' ';
76 return Complex::print(os);
77 }
78
79 int main()
80 {
81 Complex a;
82 cout << a << endl;
83
84 NameComplex b;
85 cout << b << endl;
86 }
http://topic.csdn.net/u/20110627/22/c4c0b809-13f4-482d-aa26-5faf5c1fc0f0.html?54375
posted @
2011-06-27 23:44 unixfy 阅读(236) |
评论 (0) |
编辑 收藏
还是利用字符 ASCII 定义一个表,即
static char x[256];
memset(x, 0, sizeof (x));
这样一遍扫描即可,在扫描的过程中,首先检测当前字符是否出现,如果没出现,将对应 x 的元素置为出现状态,并且将该字符加入到输出字符串中,如果已经出现过,则忽略
实现如下:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 void changestr(const char* pIn, char* pOut)
6 {
7 static char x[256];
8 int i = 0, j = 0;
9 memset(x, 0, sizeof (x));
10 for (i = 0, j = 0; i < strlen(pIn); ++i)
11 {
12 if (x[pIn[i]] == 0)
13 {
14 x[pIn[i]] = 1;
15 pOut[j] = pIn[i];
16 ++j;
17 }
18 }
19 pOut[j] = '\0';
20 }
21
22 int main()
23 {
24 char pIn[100], pOut[100];
25 while (scanf("%s", pIn) != EOF)
26 {
27 changestr(pIn, pOut);
28 printf("%s\n", pOut);
29 }
30 return 0;
31 }
posted @
2011-06-27 22:45 unixfy 阅读(544) |
评论 (0) |
编辑 收藏
一个字符串由 a - z 26 个字符组成,其中只有一个字符出现的次数为奇数次,其他 25 个字符出现次数都是偶数次。
找出这个出现奇数次的字符。
这个问题,最直观的解法就是遍历一下,记录每个字符的出现次数 int x[26] = {0};
然后扫描 x 检测即可。
但是回过头来想一下这样做有必要吗,看看我们这样做的后果是什么,我们得到了所有字符出现的次数,然后检测以得到出现次数为奇数的字符,这种方法是可以的,但是没有必要得到每个字符的出现次数,也就是说我们得到了大量的冗余信息,这种冗余信息是需要代价的。这也就导致了我们的这种方法效率不高。
把问题认识清楚很重要,最重要。我们只需要找到出现次数为奇数的字符,不需要得到每个字符的具体出现次数。我们可以利用位运算中的异或。
异或的运算性质是:
a ^ a = 0
a ^ a ^ a = a
偶数个本身异或运算为 0
奇数个本身异或运算为其本身
也就是说,我们可以对字符串中的每个字符,一遍扫描,做异或运算,由于 25 个字符出现偶数次,1 个字符出现奇数次,一遍扫描异或运算得到的结果即是出现次数为奇数的那个字符。
总结:
一个问题的解决,要从认清问题开始。求解问题的好的方法是观察我们的解决过程,看看是不是中间得到了冗余的信息,如果存在这种冗余信息,说明我们的解法做了不必要的计算,有更大的改进空间。
异或运算很巧妙。关于它的巧妙运用很多地方都有提到。其中《编程之美》中有关于异或运算的运用。
posted @
2011-06-27 18:49 unixfy 阅读(247) |
评论 (0) |
编辑 收藏
找出字符串中最大的子串
子串:当重复出现某个字符时,这个字符串就是子串
例如:
字符串 abcd13agbf
子串为:abcd13a, bcd13agb
求解 1
两重遍历字符串,检测左右两个端点的字符是否一样,如果相等,则是子串
这种方法直观,时间复杂度为 O(N ^ 2)。
求解 2
尽可能从问题中挖掘潜在的信息,获得的信息越多越有利于解决问题,也就越有可能获得高效的解法。
针对字符,我们知道其 ASCII 范围是 0 - 255 ,我们这设计一个二维数组
int x[256][100];
x 存储每个字符所在的位置
用 int n[256]; 记录每个字符出现的次数
扫描一遍字符串,即可得到我们想要的信息并存储于 x 和 n 中
然后对 x 进行扫描,即可得到最大的子串
第一次扫描字符串时间复杂度是 O(N)
第二次扫描 x ,时间复杂度也是 O(N)
总的时间复杂度为 O(N)
实现:
1 #include <iostream>
2 using namespace std;
3
4 char* maxSubStr(char* s, const char* str)
5 {
6 int left = 0, right = 0;
7 int max = 0;
8 for (int i = 0; i < strlen(str); ++i)
9 {
10 int temp = 1;
11 for (int j = i + 1; j < strlen(str); ++j)
12 {
13 if (str[i] == str[j])
14 {
15 ++temp;
16 if (temp > max)
17 {
18 max = temp;
19 left = i;
20 right = j;
21 }
22 }
23 else
24 {
25 ++temp;
26 }
27 }
28 }
29 int j = 0;
30 for (int i = left; i <= right; ++i, ++j)
31 {
32 s[j] = str[i];
33 }
34 s[j] = '\0';
35 return s;
36 }
37
38 char* maxSubStrX(char* s, const char* str)
39 {
40 static int x[256][100];
41 static int n[256];
42 memset(x, -1, sizeof (x));
43 memset(n, 0, sizeof (n));
44 for (int i = 0; i < strlen(str); ++i)
45 {
46 x[ str[i] ][ n[ str[i] ] ] = i;
47 ++n[str[i]];
48 }
49 int left = 0, right = 0;
50 int max = 0;
51 for (int i = 0; i < 256; ++i)
52 {
53 for (int j = 0; j < n[i] - 1; ++i)
54 {
55 if (x[i][j + 1] - x[i][j] > max)
56 {
57 max = x[i][j + 1] - x[i][j];
58 left = x[i][j];
59 right = x[i][j + 1];
60 }
61 }
62 }
63 int j = 0;
64 for (int i = left; i <= right; ++i, ++j)
65 {
66 s[j] = str[i];
67 }
68 s[j] = '\0';
69 return s;
70 }
71
72 int main()
73 {
74 char str[100], s[100];
75 while (cin >> str)
76 {
77 cout << maxSubStr(s, str) << endl;
78 cout << maxSubStrX(s, str) << endl;
79 }
80 return 0;
81 }
posted @
2011-06-27 18:29 unixfy 阅读(616) |
评论 (0) |
编辑 收藏
利用栈存储中缀表达式的各个元素
例如:
1 2 + 3 *
3 3 *
9
1 // 后缀表达式求解结果
2
3 #include <iostream>
4 #include <stack>
5 #include <string>
6 #include <sstream>
7 #include <algorithm>
8 using namespace std;
9
10 void printPost(const stack<string>& post)
11 {
12 stack<string> temp(post);
13 while (!temp.empty())
14 {
15 cout << temp.top() << ' ';
16 temp.pop();
17 }
18 cout << endl;
19 }
20
21 void clearPost(stack<string>& post)
22 {
23 while (!post.empty())
24 {
25 post.pop();
26 }
27 }
28
29 void getPost(stack<string>& post)
30 {
31 clearPost(post);
32 string t;
33 stack<string> temp;
34 while (cin >> t)
35 {
36 temp.push(t);
37 }
38 while (!temp.empty())
39 {
40 post.push(temp.top());
41 temp.pop();
42 }
43 }
44
45 double computePost(const stack<string>& rhs)
46 {
47 stack<string> post(rhs);
48 double d1, d2;
49 double dd;
50 string optor;
51 string temp;
52 while (post.size() >= 3)
53 {
54 d1 = atof(post.top().c_str());
55 post.pop();
56 d2 = atof(post.top().c_str());
57 post.pop();
58 optor = post.top();
59 post.pop();
60 switch (optor[0])
61 {
62 case '+':
63 dd = d1 + d2;
64 break;
65 case '-':
66 dd = d1 - d2;
67 break;
68 case '*':
69 dd = d1 * d2;
70 break;
71 case '/':
72 dd = d1 / d2;
73 break;
74 default:
75 break;
76 }
77 if (post.empty())
78 {
79 break;
80 }
81 stringstream ss;
82 ss << dd;
83 ss >> temp;
84 post.push(temp);
85 printPost(post);
86 }
87 return dd;
88 }
89
90 int main()
91 {
92 stack<string> post;
93 cout << "Input:" << endl;
94 getPost(post);
95 printPost(post);
96 cout << computePost(post) << endl;
97 return 0;
98 }
posted @
2011-06-25 19:10 unixfy 阅读(411) |
评论 (0) |
编辑 收藏
字符转换函数的实现
第一种方法,利用 ASCII 码大小计算
1 char mytoupper(char c)
2 {
3 if (c >= 'a' && c <= 'z')
4 {
5 c += ('A' - 'a');
6 }
7 return c;
8 }
9
10 char mytolower(char c)
11 {
12 if (c >= 'A' && c <= 'Z')
13 {
14 c += ('a' - 'A');
15 }
16 return c;
17 }
第二种方法,利用位运算
'a' - 'z': 97 - 122
'A' - 'Z': 65 - 90
'a' 与 'A' 正好相差 32 ,即 20x ,0010 0000
大写字母的范围是 0100 0001 - 0101 1010
小些字母的范围是 0110 0001 - 0111 1010
对于大写字母第 5 位都为 0
对于小些字母第 5 为都为 1
可以利用位运算的方法,即对大写字母的第 5 位进行操作,但要保持其他位不变
即利用 MASK = 0010 0000
大写 -> 小写
'a' = 'A' | (0010 0000);
小写 -> 大写
'A' = 'a' & (1101 1111);
这样做也不需要检测,如果本来就是小写,在做 或 操作时,第 5 位不变,维持 1
如果本来就是大写,在做 与操作时,第 5 位还是不变,维持 0
1 char mytoupper(char c)
2 {
3 return c & (0xDF);
4 }
5
6 char mytolower(char c)
7 {
8 return c | (0x20);
9 }
http://www.cppblog.com/qinqing1984/archive/2011/06/25/149427.html
posted @
2011-06-25 18:24 unixfy 阅读(103) |
评论 (0) |
编辑 收藏
http://blog.csdn.net/v_JULY_v一个算法的博客
几个算法题目
1.
实现过程中参考了网上别人的博客,主要思想是利用一个辅助栈记录 min 的索引。
1 #include <iostream>
2 #include <ctime>
3 #include <cassert>
4 using namespace std;
5
6 class MinStack
7 {
8 private:
9 int stack[100];
10 int p;
11 int minstack[100];
12 int q;
13 public:
14 MinStack() : p(0), q(0) {}
15 bool empty()
16 {
17 return p == 0;
18 }
19 bool minEmpty()
20 {
21 return q == 0;
22 }
23 void push(int i)
24 {
25 stack[p++] = i;
26 if (minEmpty())
27 {
28 minstack[q++] = p - 1;
29 }
30 else
31 {
32 if (i <= stack[minTop()])
33 {
34 minstack[q++] = p - 1;
35 }
36 }
37 }
38 void pop()
39 {
40 assert(!empty());
41 if (top() == stack[minTop()])
42 {
43 minPop();
44 }
45 --p;
46 }
47 int min()
48 {
49 assert(!empty());
50 return stack[minTop()];
51 }
52 void minPop()
53 {
54 assert(!minEmpty());
55 --q;
56 }
57 int top()
58 {
59 assert(!empty());
60 return stack[p - 1];
61 }
62 int minTop()
63 {
64 assert(!minEmpty());
65 return minstack[q - 1];
66 }
67 };
68
69 int main()
70 {
71 MinStack ms;
72 srand(time(0));
73 for (int i = 0; i < 10; ++i)
74 {
75 int n = rand() % 100;
76 ms.push(n);
77 }
78 while (!ms.empty())
79 {
80 cout << ms.top() << '\t' << ms.min() << endl;
81 ms.pop();
82 }
83 return 0;
84 }
2.
1 /*
2 *
3 *先统计所有查询的次数,所有查询有 300 万个,255 * 300 * 10000B = 765 MB,可以存入内存。这里使用 STL 中的 map。所得时间复杂度为 O(NlogM),N 为所有的查询,包括重复的,M 为不重复的查询。更好的方法是用散列。
4 *
5 *然后遍历 map,维护一个大小为 10 的集合,在遍历 map 时,比较当前查询的出现次数与集合中出现次数最小的查询的出现此时比较,如果大于,将当前查询替换到集合中。
6 *这里的集合还是用的 map,时间复杂度为 O(MlogK),这里 K = 10。
7 *
8 */
9
10 #include <iostream>
11 #include <fstream>
12 #include <map>
13 #include <string>
14 using namespace std;
15
16 void statistics(map<string, int>& data, const string& query)
17 {
18 ++data[query];
19 }
20
21 void findTopK(multimap<int, string>& topK, int k, const map<string, int>& data)
22 {
23 topK.clear();
24 for (map<string, int>::const_iterator cit = data.begin(); cit != data.end(); ++cit)
25 {
26 if (topK.size() < k)
27 {
28 topK.insert(make_pair(cit->second, cit->first));
29 }
30 else
31 {
32 if (cit->second > topK.begin()->first)
33 {
34 topK.erase(topK.begin());
35 topK.insert(make_pair(cit->second, cit->first));
36 }
37 }
38 }
39 }
40
41 int main()
42 {
43 ifstream fin("queryfile.txt");
44 map<string, int> data;
45 multimap<int, string> top10;
46 string query;
47 while (getline(fin, query))
48 {
49 statistics(data, query);
50 }
51 findTopK(top10, 10, data);
52 for (multimap<int, string>::const_reverse_iterator cit = top10.rbegin(); cit != top10.rend(); ++cit)
53 {
54 cout << cit->second << '\t' << cit->first << endl;
55 }
56
57 return 0;
58 }
3.
1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 char solve(const string& s)
6 {
7 static int times[26] = {0};
8 memset(times, 0, sizeof (times));
9 for (size_t i = 0; i < s.size(); ++i)
10 {
11 ++times[s[i] - 'a'];
12 }
13 for (size_t i = 0; i < s.size(); ++i)
14 {
15 if (times[s[i] - 'a'] == 1)
16 {
17 return s[i];
18 }
19 }
20 return 0;
21 }
22
23 int main()
24 {
25 string s = "abaccdeff";
26 cout << solve(s) << endl;
27 return 0;
28 }
posted @
2011-06-25 16:44 unixfy 阅读(88) |
评论 (0) |
编辑 收藏
除以 1000 , 对余数进行处理
1 #include <iostream>
2 using namespace std;
3
4 char* reverse(char* s, int low, int high)
5 {
6 while (low < high)
7 {
8 s[low] ^= s[high];
9 s[high] ^= s[low];
10 s[low] ^= s[high];
11 ++low;
12 --high;
13 }
14 return s;
15 }
16
17 char* format_thousands_separator(char a[], unsigned long val)
18 {
19 char* ret = a;
20 char temp[4];
21 int t;
22 int n = 0;
23 while (val > 1000)
24 {
25 t = val % 1000;
26 if (t >= 100)
27 {
28 itoa(t, temp, 10);
29 reverse(temp, 0, 2);
30 //cout << temp << endl;
31 strcat(ret, temp);
32 //cout<< "test" << ret << endl;
33 }
34 else if (t >= 10)
35 {
36 itoa(t, temp, 10);
37 reverse(temp, 0, 1);
38 strcat(ret, temp);
39 strcat(ret, "0");
40 }
41 else
42 {
43 itoa(t, temp, 10);
44 strcat(ret, temp);
45 strcat(ret, "00");
46 }
47 strcat(ret, ",");
48 n += 4;
49 val /= 1000;
50 ret[n] = '\0';
51 cout << ret << endl;
52 }
53 if (val >= 100)
54 {
55 itoa(val, temp, 10);
56 reverse(temp, 0, 2);
57 strcat(ret, temp);
58 n += 3;
59 }
60 else if (val >= 10)
61 {
62 itoa(val, temp, 10);
63 reverse(temp, 0, 1);
64 strcat(ret, temp);
65 n += 2;
66 }
67 else
68 {
69 itoa(val, temp, 10);
70 strcat(ret, temp);
71 ++n;
72 }
73 reverse(ret, 0, n - 1);
74 ret[n] = '\0';
75 return ret;
76 };
77
78 int main()
79 {
80 unsigned long ul;
81 char sul[20] = {0};
82 while (cin >> ul)
83 {
84 cout << format_thousands_separator(sul, ul) << endl;
85 }
86 return 0;
87 }
先转换成一个 字符串 ,然后从右扫描,加逗号,然后反转
1 #include <iostream>
2 #include <sstream>
3 #include <string>
4 #include <algorithm>
5 using namespace std;
6
7 const string& format_thousands_separator(string& s, unsigned long val)
8 {
9 s.clear();
10 char t[20];
11 string temp(ltoa(val, t, 10));
12
13 int n = 0;
14 for (string::const_reverse_iterator cit = temp.rbegin(); cit != temp.rend(); ++cit)
15 {
16 ++n;
17 s += *cit;
18 if (n == 3)
19 {
20 s += ',';
21 n = 0;
22 }
23 }
24 reverse(s.begin(), s.end());
25 return s;
26 }
27
28 int main()
29 {
30 unsigned long ul;
31 string sul;
32 while (cin >> ul)
33 {
34 cout << format_thousands_separator(sul, ul) << endl;
35 }
36 return 0;
37 }
http://www.cppblog.com/qinqing1984/archive/2011/06/24/149366.html
posted @
2011-06-24 16:46 unixfy 阅读(468) |
评论 (0) |
编辑 收藏