对字符串中的所有单词进行倒排。
说明:
1、构成单词的字符只有26个大写或小写英文字母;
2、非构成单词的字符均视为单词间隔符;
3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;
4、每个单词最长20个字母;
数据范围:字符串长度满足
对字符串中的所有单词进行倒排。
说明:
1、构成单词的字符只有26个大写或小写英文字母;
2、非构成单词的字符均视为单词间隔符;
3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;
输入一行,表示用来倒排的句子
输出句子的倒排结果
I am a student
student a am I
$bo*y gi!r#l
l r gi y bo
int main() { char str[10001]; gets(str);//获取输入字符 //判断数组中元素是否都在范围内,如果不在则替换为空格 for (int i = 0; i < strlen(str); i++) { if (!(str[i]>='A')&&str[i]<='z') { str[i] = ' '; } } int len = strlen(str);//获取长度 //从尾部进行判断,遇到空格则输出字符,输出之后把输出了的单词丢掉,输出格式中的单词间隔由printf去添加 while (len--) { if (str[len] == ' ') { printf("%s ",&str[len+1]); str[len] = '\0'; //printf("%s ",str); } } printf("%s ",&str[len+1]);//输出最后一个单词 return 0; }最后一个的单词输出应该可以改进,大佬们看看有什么办法
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> char* process_blank(char str[], int len); char* reverse_word(char* str, int len); int main() { char word[100001]; int len = 0, out_len = 0; fgets(word, 100000, stdin); word[strcspn(word, "\n")] = '\0'; // 去掉换行符 word[100001] = '\0'; // 防止越界 char* chr = (char*)malloc(strlen(word) * sizeof(char)); if (chr == NULL) { return 1; // 错误处理:内存分配失败 } chr = process_blank(word, strlen(word)); chr = reverse_word(word, strlen(word)); printf("%s\n", chr); free(chr); return 0; } /* @brief 将字符数组中连续的非字母字符替换成一个空格并返回处理后的字符数组 * @param str 待处理的字符串 * @param len 字符串长度 * @return 处理后的字符串 */ char* process_blank(char* str, int len) { int index = 0; if (str == NULL || len <= 0) { return NULL; // 错误处理:输入无效 } for (int i = 0; i < len - 2; i++) { if (!isalpha(str[i]) && !isalpha(str[i + 1])) { str[i] = str[i + 1]; } } for (int i = 0; i < len; i++) { if (!isalpha(str[i])) { str[i] = ' '; } } return str; } /* * @brief 将已经翻转过的字符串中每个单词的顺序颠倒并返回处理后的字符数组 * @param str 待处理的字符串 * @param len 字符串长度 * @return 处理后的字符串 */ char* reverse_word(char* str, int len) // 逆序单词 { int i = 0, j = 0; if (str == NULL || len <= 0) { return NULL; // 错误处理:输入无效 } char* out = (char*)malloc((len + 1) * sizeof(char)); //申请多加一个位置用来添加结束符号 if (out == NULL) { return NULL; // 错误处理:内存分配失败 } //第一次循环翻转整个字符串 for (i = 0, j = len - 1; i < len && j >= 0; i++, j--) { out[i] = str[j]; } out[len + 1] = '\0'; // 防止越界 //第二次循环翻转每个单词,单词以空格划分 int start = 0, end = 0; while (end <= len) { // 找到单词的结束位置 if (out[end] == ' ' || out[end] == '\0') { int word_end = end - 1; // 翻转当前单词 while (start < word_end) { char temp = out[start]; out[start] = out[word_end]; out[word_end] = temp; start++; word_end--; } start = end + 1; // 更新起始位置到下一个单词的开始 } end++; // 移动到下一个字符 } return out; }
#include <stdio.h> #include <string.h> /*翻转单词*/ void reverse(char *s, int start, int end){ char temp; for(int i = start, j = end; i < j; i++, j--){ temp = s[i]; s[i] = s[j]; s[j] = temp; } } /*删除多余空格 双指针法*/ void deleteExtraSpace(char *s){ int fastIndex = 0, slowIndex = strlen(s) - 1; while((s[fastIndex] > 'Z' && s[fastIndex] < 'a') || s[fastIndex] < 'A' || s[fastIndex] > 'z'){ fastIndex++; } while((s[slowIndex] > 'Z' && s[slowIndex] < 'a') || s[slowIndex] < 'A' || s[slowIndex] > 'z'){ slowIndex--; } int index = 0; /*边界: i <= slowindex 因为i == slowIndex是有意义的*/ for(int i = fastIndex; i <= slowIndex; i++){ if(((s[i] > 'Z' && s[i] < 'a') || s[i] < 'A' || s[i] > 'z') && \ ((s[i+1] > 'Z' && s[i+1] < 'a') || s[i+1] < 'A' || s[i+1] > 'z')){ continue; } if((s[i] > 'Z' && s[i] < 'a') || s[i] < 'A' || s[i] > 'z'){ s[index] = ' '; } else{ s[index] = s[i]; } index++; } s[index] = '\0'; } int main() { char str[10001] = {0}; int num = 0; int x = 0; /**/ fgets(str, sizeof(str), stdin); int len = strlen(str); str[len - 1] = '\0'; deleteExtraSpace(str); len = strlen(str); reverse(str, 0, len - 1); int start = 0; /*边界: i <= len 因为i == len说明是最后一个单词的末尾 对最后一个单词进行反转*/ for(int i = 0; i <= len; i++){ if(((str[i] > 'Z' && str[i] < 'a') || str[i] < 'A' || str[i] > 'z') || str[i] == '\0'){ reverse(str, start, i - 1); start = i + 1; } } printf("%s\n", str); return 0; } 来着“卡尔”的思路 采用了双指针法 O(1)的空间复杂度,O(n)的时间复杂度
#include <stdio.h> #include <string.h> int main() { char s[21] = {0}; char words[500][21] = {0}; int i = 0, j = 0, len; char c = getchar(); while (c != '\n') { if (c >= 65 && c < 91 || c >= 97 && c < 123) { words[i][j++] = c; } else { i++; j = 0; } c = getchar(); } len = i + 1; for (i = 0, j = len - 1; i < j; i++, j--) { strncpy(s, words[i], 21); strncpy(words[i], words[j], 21); strncpy(words[j], s, 21); } for (i = 0; i < len; i++) { printf("%s ", words[i]); } return 0; }
#include <stdio.h> #include <string.h> int main() { char str[10000] = "0"; gets(str); size_t sz = strlen(str) - 1; char* dress = str + sz; while (dress >= str) { char* zimu = dress; while (*dress >= 'a' && *dress <= 'z' || *dress >= 'A' && *dress <= 'Z') { dress--; } for (char* i = dress + 1; i <= zimu; i++) { printf("%c", *i); } while ((*dress < 'a' || *dress>'z') && (*dress < 'A' || *dress>'Z') ) { dress--; } printf("%c", ' '); } return 0; }
#include <ctype.h> #include <stdio.h> #include <string.h> int main() { char s[10000]; gets(s); int k = strlen(s), kong[10000] = {0}, m = 0; for (int i = 0; i < k; i++) { //剔除杂符号 换为空格 if (isupper(s[i])) continue; else if (islower(s[i])) continue; else s[i] = ' '; } char ns[10000] = {'\0'}; // 剔除多余空格,记录空格的位置 for (int i = 0, j = 0, b = 1; i < k; i++) { if (s[i] != ' ') {ns[j++] = s[i];b = 1;} else { if (b) {kong[m++] = j;ns[j++] = s[i];} b = 0; } } //以上处理ns中有m个空格 存在kong[]中 开始打印 if (m == 0)puts(ns); else { for (int i = strlen(ns)-1, j = m-1; j >= 0; j--) { for (k = kong[j]+1 ; k <=i ; k++) putchar(ns[k]); putchar(' '); i = kong[j]-1 ; } } for (k = 0; k < kong[0]; k++)putchar(ns[k]); return 0; }
#include <stdio.h> #include <string.h> int main() { char str[10001]={0}; int len,chr_count; char *ptmp; gets(str); chr_count = len = strlen(str); //去除特殊字符 while(len--) { if((str[len] < 'A' || str[len] > 'Z') && (str[len] < 'a' || str[len] > 'z')) { str[len] = '\0'; } } ptmp = str; while(chr_count--) { if((ptmp[chr_count] == '\0') && (ptmp[chr_count+1] != '\0')) { printf("%s ", &ptmp[chr_count+1]); } } printf("%s\n",str); return 0; }
#include <stdio.h> //扫描字符串。如果是英文,则将其写入二维数组当中, 遇到非英文,写入截止符号\0。倒序输出二维数组,中间穿插空格即可。 //flag == 0即为写入英文状态, 1即为当前是间隔符。 int main() { char c, str[100][21]; int i = 0, j = 0, flag = 0; /*扫描字符串*/ while(scanf("%c", &c) != EOF){ /*大写*/ if(c >= 'A' && c <= 'Z'){ str[i][j++] = c; flag = 0; } /*小写*/ else if(c >= 'a' && c <= 'z'){ str[i][j++] = c; flag = 0; } /*第1个非英文*/ else if(flag == 0){ str[i++][j] = '\0'; //换行 j = 0; //列号归零 flag = 1; } } /*输出*/ for(i=i-1; i>=0; i--) //while循环结束后i==行数 printf("%s ", str[i]); return 0; }
#include <stdio.h> #include <string.h> int main() { char str[10001] = {}; gets(str); int len = strlen(str); int word_len = 0; int flag = 0; //多个间隔符时,倒排转换后只允许出现一个空格间隔符 //从后往前遍历,遇到字母计算单词长度,遇到其他字符就打印 for (int i = len - 1; i >= 0; i--) { if (isalpha(str[i])) { word_len++; flag = 1; continue; } else { if (flag == 1) { for (int j = i + 1; j < i + 1 + word_len; j++) { printf("%c", str[j]); } printf(" "); flag = 0; word_len = 0; } } } //打印最后一个单词 if (isalpha(str[0])) { for (int i = 0; i < word_len; i++) printf("%c", str[i]); } return 0; }