首页 > 试题广场 >

单词倒排

[编程题]单词倒排
  • 热度指数:381950 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

对字符串中的所有单词进行倒排。

说明:

1、构成单词的字符只有26个大写或小写英文字母;

2、非构成单词的字符均视为单词间隔符;

3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;

4、每个单词最长20个字母;

数据范围:字符串长度满足

输入描述:

输入一行,表示用来倒排的句子



输出描述:

输出句子的倒排结果

示例1

输入

I am a student

输出

student a am I
示例2

输入

$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;
}
最后一个的单词输出应该可以改进,大佬们看看有什么办法
发表于 2024-11-12 20:07:20 回复(0)
# 本人的菜鸟式解法。
#用到:Ctype函数判符号,双指针,堆内存数组,strcspn
#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;
}


发表于 2024-11-05 10:29:11 回复(0)
#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)的时间复杂度

发表于 2024-09-24 19:33:09 回复(0)
#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;
}
发表于 2024-09-19 09:29:54 回复(0)
#include <stdio.h>
#include <string.h>
int main() {
    char arr[1100]={'0'};
    gets(arr);
    char* res;
    int len = strlen(arr);
    int i=0;
    int size=0;
    for(i=len-1;i>=0;i--){
        if((arr[i]<'a'||arr[i]>'z')&&(arr[i]<'A'||arr[i]>'Z')){
            arr[i] = '\0';
        }
    }
    res = arr;
    while(len--){
        if((res[len]=='\0')&&(res[len+1]!='\0')){
            printf("%s ", &res[len+1]);
        }
    }
    printf("%s", arr);
    return 0;
}
发表于 2024-08-06 00:06:27 回复(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;
}

发表于 2024-05-05 12:21:20 回复(0)
#include <stdio.h>
#include<string.h>
#include<assert.h>
#include<ctype.h>

void reverse(char*left,char*right)
{
    assert(left&&right);
    while(left<right)
    {
        char ch=*left;
        *left=*right;
        *right=ch;
        left++;
        right--;
    }

}

int main() {
    char str[10001]={0};//确保有结束标志
    int i=0;
    char ch;
    int flag=0;
    while((ch=getchar())!=EOF)
    {
        if(isalpha(ch))
        {
            str[i++]=ch;
            flag=1;
        }
        else
        {
            if(flag==1)
            {
                if(ch!='\n')//最后一个回车不读进去
                {
                    str[i++]=' ';
                    flag=0;
                }
             
            }
        }
    }
    int len=strlen(str);
    reverse(str,str+len-1);
    char* begin=str;
    char* end=str;
    while(*end!='\0')
    {
        begin=end;
        if(isalpha(*end))
        {
            while(isalpha(*end))
            {
                end++;
            }
            reverse(begin,end-1);
        }
        else {
        end++;
        }
    }
    printf("%s",str);
    return 0;
}
编辑于 2024-03-31 17:56:53 回复(0)
#include <stdio.h>
#include <string.h>
int main() {
    char str[10001];
    gets(str);
    int len=strlen(str);
    for(int i=0;i<len;i++)
    {
        if(str[i]>='A'&&str[i]<='Z') ;
        else if(str[i]>='a'&&str[i]<='z') ;
        else
            str[i]=' ';
        if(i>0&&str[i]==' '&&(str[i-1]==' '||str[i-1]==EOF))
            str[i]=EOF;
    }
    int a=len-1,b=len-1;/*用a标示每个空格的位置*/
    while(a>=0)
    {
        while(str[a]!=' '&&a>=0)
            a--;
        for(int j=a+1;j<=b;j++)
        {
            if(str[j]==EOF)
                continue;
            printf("%c",str[j]);
        }
        if(a>0)
            printf(" ");
        a--;
        b=a;
    }
    return 0;
}

编辑于 2024-03-12 22:06:24 回复(0)
#include<stdio.h>
#include<string.h>
char check(char t)
{
    if((t>='a'&&t<='z')||(t>='A'&&t<='Z'))
    {
        return 1;
    }
    else{
        return 0;
    }
}
int main()
{
    char str[1000];
    int len,i,j,head,tail,flag;
    scanf("%[^\n]",&str);
    len = strlen(str);
    head = tail = flag = len;
    for(i = len-1;i>=0;i--)
    {
        if(i==len-1&&check(str[i]))
        {
            tail = i;
            //printf("%d ",tail);
        }
         if(check(str[i])&&!check(str[i+1])&&i!=len-1)
        {
            tail = i;
            //printf("%d ",tail);
        }
         if(check(str[i])&&i==0)
        {
            head = i;
            //printf("%d ",head);
        }
         if(check(str[i])&&!check(str[i-1])&&i!=0)
        {
            head = i;
            //printf("%d ",head);
        }
        if(head<=tail&&tail<flag)
        {
            for(j=head;j<=tail;j++)
            {
                printf("%c",str[j]);
            }
            head = tail = len;
            printf(" ");
            flag = tail;
        }

    }
    return 0;
}
编辑于 2024-03-07 21:46:35 回复(0)
写的又臭又长啊
# define _CRT_SECURE_NO_WARNINGS
# include<stdio.h>
# include<string.h>
int main()
{
    char input[10001] = { 0 };
    gets(input);
    int sz = strlen(input);
    for (int i = 0; i < sz; i++)
    {
        if (input[i] < 'A' || input[i]>'Z' && input[i] < 'a' || input[i]>'z')
        {
            input[i] = ' ';
        }
    }
    char* first = input;
    char* last = &input[0] + (sz-1);
    char temp = 0;
    while (last > first)
    {
        temp = *first;
        *first = *last;
        *last = temp;
        last--;
        first++;
    }
    char* start = input;
    char* end = input;
    char* temp2 = { NULL };
    temp = 0;
    for (int i = 0; i < sz; i++)
    {
        if (*end != ' '&&*end !='\0')
        {
            end++;
        }
        else
        {
            temp2 = end;
            while ((end-1) > start)
            {
                temp = *start;
                *start = *(end-1);
                *(end-1) = temp;
                end--;
                start++;
            }
            start = temp2 + 1;
            end = temp2 + 1;
        }
    }
    while ((end - 1) > start)
    {
        temp = *start;
        *start = *(end - 1);
        *(end - 1) = temp;
        end--;
        start++;
    }
    printf("%s", input);
    return 0;
}


编辑于 2024-02-23 16:48:32 回复(0)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    char arr[2000] = { 0 };
    long long b = 0;
    int arr1[1000] = { 0 };
    for (long long i = 0; i < 2000; i++)
    {
        scanf("%c", &arr[i]);
        if (arr[i] < 65 || arr[i]>122)
        {
            b++;
            arr1[b] = i+1;
            
        }
        if (arr[i] == '\n')
        {
            break;
        }
    }
    long long a = b;
    while (a)
    {
        long long i = 0;
        for (i = arr1[b - 1]; i < arr1[b]-1; i++)
        {
            printf("%c", arr[i]);
        }
        printf(" ");
        a--;
        b--;
    }
    return 0;
}
发表于 2024-01-11 13:16:24 回复(1)
#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;
    }

编辑于 2023-12-02 18:08:59 回复(0)
1.思路:
(1)字符串中有空格,故整个字符串用gets获取
(2)遍历字符串的每个字符,将非字母的字符位置填 '\0'
(3)再次从整个字符串的末尾往前遍历,遇到i处为\0,而i+1处非\0时,i+1处即可打印一个字符串
(4)注意从后往前遍历,记得最终把第一个单词也打印一下
2.注意事项:
(1)记得保留原始字符串的字符个数,循环时对len--了,第二个循环容易错用len。
(2)注意临时指针不要指错。
#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;
}


发表于 2023-11-25 22:38:48 回复(0)
#include <ctype.h>
#include <stdio.h>
#include <string.h>

int main() {
    char str[10001] = {'\0'};
    gets(str);
    int len = strlen(str);
    int flag = 0;
    for(int i  = len-1;i>=0;i--)
    {
        //判断是否是字母,且只出现一次非字母
        if(!isalpha(str[i])&&flag == 0)
        {
            printf("%s ",&str[i+1]);
            str[i] = '\0';
            flag = 1;
        }
        else if(isalpha(str[i])&&flag==1)
        {
            flag = 0;
        }
    }
    //如果最后flag还是0表示还需要打印最后一个字母字符串
    if(flag == 0)
    {
        printf("%s",str);
    }
    printf("\n");
    return 0;
}
发表于 2023-10-10 12:49:39 回复(0)
#include <stdio.h>
#include <string.h>
//思路:寻找非英文字母,若其后一个为英文字母则开始输出,否则不输出
int isEnglish(char c) { //判断是否为英文字母
    int flag = 0;
    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) //是
        flag = 1;
    else//不是
        flag = 0;
    return flag;
}
int main() {
    char str[10001] = {0};
    gets(str);
    int len = strlen(str);
    for (int i = len - 1; i >= 0; i--) {
        if (isEnglish(str[i]) == 0 && isEnglish(str[i + 1]) == 1) {
            int j = i + 1;
            while (isEnglish(str[j]) == 1) {
                //一个单词
                printf("%c", str[j]);
                j++;
            }
            printf(" ");
        }
    }
    //第一个字符为字母
    if (isEnglish(str[0]) == 1) {
        printf("%c", str[0]);
        int j = 1;
        while (isEnglish(str[j]) == 1) {
            //一个单词
            printf("%c", str[j]);
            j++;
        }
    }
    return 0;
}
发表于 2023-09-03 20:45:53 回复(0)
#include <stdio.h>
#include <string.h>
int main(){
    char s[10001];
    int len,i;
    gets(s);
    len=strlen(s);
    for(i=len-1;i>=0;i--)
    {
        if(!(s[i]>='A'&&s[i]<='Z'||s[i]>='a'&&s[i]<='z'))
        {
            printf("%s ",&s[i+1]);
            s[i]='\0';
        }
    }
    printf("%s",&s[0]);
    return 0;
}
发表于 2023-07-30 22:50:39 回复(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;
}

发表于 2023-07-08 17:23:16 回复(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;
}

发表于 2023-02-25 21:01:56 回复(0)