居然有一个同学想到了使用数组下标和ASCII表做了一个很漂亮的映射完成了这道题目,以前反正我是没想到的。
#ifndef _TEST_H #define _TEST_H #include <iostream> #include <iomanip> using namespace std; //find a character in a string, if not in the string return -1 //else return the index it occure in the string int uniq(char ch, char* pCh) { int flag = -1; int i = 0; for (i = 0; *pCh != '\0'; pCh++) { if (ch == *pCh) { flag = 0; break; } i++; } if (flag == -1) return -1; else return i; } void main() { //use the array of num and uch as a map int num[100] = {0}; //caculate the numbers of the uniq character char uch[100] = {0};//store the uniq character char ch[100]; cout << "enter the string you want to caculate: " << endl; cin >> ch; int j = 0; //record the index of the array of num and uch //use the uniq function to construct the map(the array of uch and num) for (int i = 0; ch[i] != '\0'; i++) { if(uniq(ch[i],uch) == -1) { uch[j] = ch[i]; num[j]++; j ++; } else num[uniq(ch[i],uch)]++; } //print the uniq character and it's occurance number for (int m = 0;uch[m] != '\0';m++) cout << setw(2) << uch[m] << " : " << setw(2) << num[m] << endl; } /************************************************************************/ /* 还有很巧的思路: 思路一:利用ASCII码表,开一个128个长度的int数组chasc并初始化为0, 因为最多有128个字符。然后把输入的字符串的每个字符提取出来,作为 chasc数组的小标(当字符做下标的时候就会把这个字符转为整数,而 这个整数恰好是它对应的ASCII码值),并把这个下标单元的值加1,即 出现次数增加1,遍历完输入的字符串数组之后就已经统计完毕了。输出 的时候只要在chasc数组中不为0的值就是已经出现的,把下标强制转换char 类型输出来就是对应出现的字符,把这个下标下内容取出来就是这个字符 出现的次数。!!!十分巧妙的map!!!这可是一个大一新生做出来的啊, 佩服!这个是我目前想到和看到的最简洁的方法。 思路二:遍历输入的数组,这里的方法在于去重。也是对应这个输入的字符 数组做一个足够大的int型数组并初始化为1表示只要出现的字符就是至少出 现了一次。之后开始遍历这个字符串,每次都先判断对应num位置是否是1, 如果是1则向后遍历,如果不是则跳过,因为已经统计过了。 从第一个开始,看之后的n-1个,如果发现有重复出现的就把二者对应的num 中的位置的值都加1,这样num第一个位置记录的就是这个字符出现的次数, 而后面重复出现的位置都上num对应单元都是2了,输出这个字符和出现的次数; 从第二个对应num位置不为1的开始,看之后的n-i个,统计并输出直至字符串 结束。其实也是做了一个map,只不过重点在于去重。 注意:如果要统计空格输出的次数这样是不行的,因为到空格就当作了字符串 结束的标识位*/ /************************************************************************/ #endif //_TEST_H