在一行上输入若干个字符串,每个字符串长度为
,仅由大小写字母构成,代表一个单词。单词间还夹杂了一定数量的非字母字符(但保证是可见字符),代表分隔符。
除此之外,保证总字符长度不超过
。
在一行上输出一个句子,代表以单词为单位逆序排放的结果。单词间使用单个空格分隔。
Nowcoder Hello
Hello Nowcoder
$bo*y gi!r#l
l r gi y bo
#include <stdio.h>
int main() {
char word[500][21];
char c;
int i,j=0;
for(i=0;(c=getchar())!=EOF;i++){
if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){word[j][i]=c;}
else{i=-1;j++;continue;}
}
for(i=j-1;i>=0;i--){
printf("%s ",word[i]);
}
return 0;
} 既然题目给了范围,那我们直接预设一个空的字符串数组,字母就读取,非字母就换行,最后逆着打印每一行即可。
#include <stdio.h>
#include <string.h>
#define MAXSTRINGLEN 10000
#define Isletter 0
#define Isanother 1
int Isletteroranother(char *str);
int main()
{
char str[MAXSTRINGLEN + 2] = {0};
int i, j, len;
str[0] = ' ';
scanf("%[^\n]", &str[1]);
len = strlen(str);
i = len;
while (i--)
{
if (Isletteroranother(&str[i]))
{
j = i + 1;
while (!Isletteroranother(&str[j]))
{
printf("%c", str[j]);
j++;
}
printf(" ");
}
}
return 0;
}
int Isletteroranother(char *str)
{
if (*str >= 'A' && *str <= 'Z')
{
return Isletter;
}
if (*str >= 'a' && *str <= 'z')
{
return Isletter;
}
return Isanother;
} 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;
}