实现删除字符串中出现次数最少的字符,若出现次数最少的字符有多个,则把出现次数最少的字符都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。
数据范围:输入的字符串长度满足 ,保证输入的字符串中仅出现小写字母
字符串只包含小写英文字母, 不考虑非法输入,输入的字符串长度小于等于20个字节。
删除字符串中出现次数最少的字符后的字符串。
aabcddd
aaddd
//这道题卡我几天。注释很全,牛友可看。
/*实现删除字符串中出现次数最少的字符,若出现次数最少的字符有多个,则把出现次数最少的字符都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。*/ #include <stdio.h> #include <ctype.h> #include <string.h> #define LEN_DEL_INDEX 20 //因为题目要求字符串长度不超过20 /* * @Brief:打印二维数组; * @Note:专门用来debug的; */ void print_2D_array(int kv[][2], int rows) { for (int i = 0; i < rows; i++) { printf("%d %d\n", kv[i][0], kv[i][1]); } } /* * @brief:删除字符串里的指定元素,不论元素的位置。 * @param:ddel:要删除的元素,s:字符串,len:字符串长度 */ void proc_del_letter(char ddel, char* str, int* len) { int i, j; for (i = 0, j = 0; i < *len; i++) { if (str[i] != ddel) { str[j++] = str[i]; // 仅当当前字符不是要删除的字符时,才将其复制到新位置 } } str[j] = '\0'; // 确保字符串以空字符结尾 *len = j; // 更新字符串长度 } /* * @brief:冒泡排序二维数组,按照次数升序排列。 * @param:hash:待排序的二维数组,rows:行数 * @retval:None */ void upsort(int hash[][2], int rows) { if (rows < 0) { exit(-1); } if (rows == 1) return; for (int i = 0; i < rows - 1; i++) { for (int j = 0; j < rows - 1 - i; j++) { if (hash[j][1] > hash[j + 1][1]) { int temp_char = hash[j + 1][0]; int temp_freq = hash[j + 1][1]; hash[j + 1][0] = hash[j][0]; hash[j + 1][1] = hash[j][1]; hash[j][0] = temp_char; hash[j][1] = temp_freq; } } } } /* * @brief:处理字符串的主要程序 * @param:strr:待处理的字符串,len:长度 * @retval:成功返回1 */ int proc(char* strr, int len) { if (len < 1 || len > 20) return -1; int i = 0; // 定义哈希表。26个小写字母。第一列是字母,第二列是次数。 // 第一列是0说明是字符'a',第二列是0说明字符'a'出现0次。 int hash[26][2] = {0}; for (i = 0; i < 26; i++) { // 初始化二维数组 hash[i][0] = i; hash[i][1] = 0; } for (i = 0; i < len; i++) { if (!islower(strr[i])) { perror("Capital letter occur!\n"); return -1; } } for (i = 0; i < len; i++) { hash[strr[i] - 'a'][1] += 1; // 更新字符出现次数 } int rows = sizeof(hash) / sizeof(hash[0]); // printf("debug: orginal is: %s\n", strr); // print_2D_array(hash, rows); upsort(hash, 26); // printf("debug: after sort:\n"); // print_2D_array(hash, rows); //没排序值也是0,所以从0开始若某个元素不是0说明已经到排序后的字母了。 int index_not_zero = -1; //非零元素行的值的首下标 for (i = 0; i < 26; i++) { if (hash[i][1] != 0) { index_not_zero = i; break; } } int count_hash_min_indiex = 0; //统计哈希表里最小下标有几个,至少有一个但从零计数 int temp_hash_min_index = hash[index_not_zero][1]; for (i = index_not_zero; i < 26; i++) { if (hash[i][1] == temp_hash_min_index) { count_hash_min_indiex += 1; } } int count_hash_min_to_elem = 1; //统计哈希表里最小下标的对应元素有几个,至少为1。 for ( i = 0; i < len; i++) { if (strr[i] - 'a' == *hash[index_not_zero]) { count_hash_min_to_elem += 1; } } for ( i = 0; i < count_hash_min_indiex; i++) { proc_del_letter(hash[index_not_zero + i][0] + 'a', strr, &len); } return 1; } int main() { char strr[21] = "\0"; fgets(strr, sizeof(strr), stdin); strr[strcspn(strr, "\n")] = '\0'; int length = strlen(strr); if (length < 1 || length > 20) return 0; if (!proc(strr, length)) { return 0; } printf("%s\n", strr); return 0; }
#include "stdio.h" #include "string.h" //思路:输入后遍历字符串,录入出现次数,之后挑出最小的数。然后遍历输出任何大于这个出现次数的数组元素。 //注意:本题的难点和核心思想在于找准两个数组之间的下标之间的关系,以做到互不干扰却又相互影响。 int main() { //输入部分 char str[27] = {'0'};//因为之后用到了26个字母的遍历,所以所有数组都设置的大一点,防止越界。另外吐槽一点,Windows下的VS code就没越界而输出一些奇怪的东西,牛客就会,6. int num[27]= {0},temp, a = 0; scanf("%s",str); int length = strlen(str),i = 0; //遍历并录入出现次数 for(; i < length; i++) { if (str[i] >= 'a' && str[i] <= 'z' ) { num[(int)str[i]-97]++;//a的ASCII为97,这样做刚好可以把a放进num[0],也就是num的第一个,实现字符与其出现次数的数组的下标的对应。 } } //获取最小输入次数。 temp = 500;//把temp初始值设定的非常大,可以保证后面的找最小出现次数被正确地放入temp中。 for (i = 0; i < 26; i++) { if (temp > num[i] && num[i] != 0) { temp = num[i]; } } for(i = 0; i < 26; i++) { if(num[str[i] - 'a'] > temp&&num[str[i] - 'a'] !='0')//此处是本题的核心。str[i]-'a'刚好由于上文构建的对应而能和i对应上;与此同时这里不使用num[i],又可以保证不会对输出环节产生无法准确对应的干扰。 { printf("%c",str[i]); } } } //以下是开发过程中使用的部分检验过程和弯路。 //此时,各个字符出现次数录入正确。 /*for (i = 0; i < length; i++) { if (num[i] > 0) { printf("%d",num[i]); } } */ //原本的输出方式:这个输出方式会导致实质上是打出了出现次数更多的字符,而不是按照字符串的原顺序进行输出。 /*for(i = 0; i < 26; i++) { if(num[i] > temp) { for(a = 0; a < num[i]; a++) { printf("%c",(char) (i+97)); } } }*/ //printf("temp is %d\n",temp);
#include <stdio.h> #include <string.h> int main() { char str[21] = {'\0'}; int con[26] = {0}; int min = 20; gets(str); for (int i = 0; i < strlen(str); i++) con[str[i] - 'a']++; for (int i = 0; i < 26; i++) if (con[i] > 0 && con[i] < min) min = con[i]; for (int i = 0; i < 26; i++) { if (con[i] == min) { for (int j = 0; j < strlen(str); j++) { if (str[j] == i + 'a') str[j] = '0'; } } } for (int j = 0; j < strlen(str); j++) if (str[j] != '0') putchar(str[j]); return 0; }
#include <stdio.h> #include <string.h> int main() { char str[21]; int count[26] = {}; int min = 20; scanf("%s", str); for (int i = 0; i < strlen(str); i++) count[str[i] - 'a'] ++; for (int i = 0; i < 26; i++) if (count[i] < min && count[i]) min = count[i]; for (int i; i < strlen(str); i++) if (count[str[i] - 'a'] != min) printf("%c", str[i]); }
int main(void){ int flag[26] = {0}; char input[20]; gets(input); int i = 0; int count = strlen(input); for(i=0;i<count;i++){ flag[input[i]-97]++; } int jojo = count; for(i=0;i<26;i++){ if(jojo >= flag[i] && flag[i]!= 0){ jojo = flag[i]; } } for(int i=0;i<count;i++){ if(flag[input[i]-97] != jojo){ printf("%c",input[i]); } } }
#include <stdio.h> int main() { char buf[20], num[26] = {0}; char buf_len, i, j, min; scanf("%s", buf); buf_len = strlen(buf); min = buf_len + 1; /* 计算各字符出现次数 */ for(i = 0; i < buf_len; i++) { num[buf[i] - 'a']++; } /* 获取最小字符串出现概率 */ for(i = 0; i < 26; i++) { if(num[i] && num[i] < min) min = num[i]; } /* 删除最少字符 */ for(i = 0, j = 0; i < buf_len; i++) { if(num[buf[i] - 'a'] > min) buf[j++] = buf[i]; } /* 输出结果 */ buf[j] = 0; printf("%s", buf); }
#include <stdio.h> #include <string.h> int main(void) { char str[21]; int index[21] = {0}; int hash[21] = {0}; scanf("%s", str); int length = (int) strlen(str); for (int i = 0; i < length; ++i) { index[i] = 1; for (int j = 0; j < length; ++j) { if (i == j) continue; else { if (str[i] == str[j]) index[i]++; else continue; } } } for (int i = 0; i < length; ++i) { if (index[i] == 1) continue; else { for (int j = 0; j < length; ++j) { if (i == j) continue; else { if (index[i] > index[j]) { hash[i] = 1; break; } } } } } for (int k = 0; k < length; ++k) { if (hash[k] == 1) printf("%c", str[k]); else continue; } return 0; }
#include <stdio.h> #define N 21 int main() { char str[N],temp; int i=0,s=1,arr[26]={0},min=N,j; //arr[26],下标对应字母'a'到'z',数值表示出现的次数 scanf("%s",str); //min先初始化为21,后续有比它小的就修改 while(str[i]!='\0') { if(str[i]<'a'||str[i]>'z') { s=0; //s为小写字母标志,如果出现非小写字母,s=0 break; } i++; } if(s==1) { i=0; while(str[i]!='\0') { arr[str[i]-'a']+=1; i++; } for(i=0;i<26;i++) { if(arr[i]!=0&&arr[i]<min) { min=arr[i]; //min记录字符串中出现相同字符次数的最小值 } } for(i=0;i<26;i++) { if(arr[i]==min) //可能出现多个字符出现次数最少 { temp=i+'a'; //下标i+'a'==出现次数最少的字符 j=0; while(str[j]!='\0') { if(str[j]==temp) { str[j]=' '; //将该字符置为空格,后续打印的时候直接跳过 } j++; } } } i=0; while(str[i]!='\0') { if(str[i]!=' ') { printf("%c",str[i]); } i++; } } return 0; }
#include<stdio.h> int main() { char str[20] = {0}; char map[26] = {0}; int i=0; char x; char min = 20; scanf("%s",str); // 记录个数 while(*(str+i)) { x = *(str+i)-'a'; map[x]++; i++; } // 寻找最小值 for(i=0;i<26;i++) { if(map[i] && map[i]<min) min = map[i]; } // 判定输出 i=0; while(*(str+i)) { if(map[*(str+i)-'a'] != min) printf("%c",*(str+i)); i++; } return 0; }
#include<stdio.h> #include<string.h> int main(){ char str[21]; int map[26] = {0}; int i; int min = 21; char *p = str; fgets(str, 21, stdin); while(*p){ map[*p - 'a']++; p++; } for( i=0; i<26; i++){ if(map[i] < min && map[i] > 0){ min = map[i]; } } for( i=0; i<strlen(str) - 1; i++){ if(map[str[i] - 'a'] != min){ printf("%c", str[i]); } } return 0; }