首页 > 试题广场 >

字符串变形

[编程题]字符串变形
  • 热度指数:161867 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
对于一个长度为 n 字符串,我们需要对它做一些变形。

首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。

比如"Hello World"变形后就变成了"wORLD hELLO"。

数据范围: , 字符串中包括大写英文字母、小写英文字母、空格。
进阶:空间复杂度 , 时间复杂度

输入描述:
给定一个字符串s以及它的长度n(1 ≤ n ≤ 10^6)


输出描述:
请返回变形后的字符串。题目保证给定的字符串均由大小写字母和空格构成。
示例1

输入

"This is a sample",16

输出

"SAMPLE A IS tHIS"
示例2

输入

"nowcoder",8

输出

"NOWCODER"
示例3

输入

"iOS",3

输出

"Ios"
void str_conver(char *src, int start, int end, char *dst, int *index)
{
    for (int i = start; i < end; i++) {
        if (isupper(src[i])) {
            dst[(*index)++] = tolower(src[i]);
        } else {
            dst[(*index)++] = toupper(src[i]);
        }
    }
    dst[(*index)++] = ' ';
}
char* trans(char* s, int n) {
    int index = 0;
    int tmp_len = n;
    char *tmp = (char *)calloc(n + 1, sizeof(char));
    memcpy(tmp, s, tmp_len + 1);
    char *res = (char *)calloc(n + 1, sizeof(char));
    int i = tmp_len;

    while (i >= 0) {
        if (tmp[i] == ' ') {
            str_conver(tmp, i + 1, tmp_len, res, &index);
            tmp[i] = '\0';
            tmp_len = strlen(tmp);
        }
        i--;
    }
    str_conver(tmp, i + 1, tmp_len, res, &index);
    res[index - 1] = '\0';
    free(tmp);

    return res;
}
发表于 2025-05-29 10:15:50 回复(0)
void str_conver(char *src, int start, int end, char *dst, int *index)
{
    for (int i = start; i < end; i++) {
        if (isupper(src[i])) {
            dst[(*index)++] = tolower(src[i]);
        } else {
            dst[(*index)++] = toupper(src[i]);
        }
    }
    dst[(*index)++] = ' ';
}
char* trans(char* s, int n) {
    int index = 0;
    int tmp_len = n;
    char *tmp = (char *)calloc(n + 1, sizeof(char));
    memcpy(tmp, s, tmp_len + 1);
    char *res = (char *)calloc(n + 1, sizeof(char));
    int i = tmp_len;

    while (i >= 0) {
        if (tmp[i] == ' ') {
            str_conver(tmp, i + 1, tmp_len, res, &index);
            tmp[i] = '\0';
            tmp_len = strlen(tmp);
        }
        i--;
    }
    str_conver(tmp, i + 1, tmp_len, res, &index);
    res[index - 1] = '\0';
    free(tmp);

    return res;
}
发表于 2025-05-26 19:29:37 回复(0)
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param s string字符串
 * @param n int整型
 * @return string字符串
 */
#include <stdio.h>
#include <string.h>
char* trans(char* s, int n ) {
    // write code here
    char* ret_sp = malloc(n + 1);
    int i = 0;
    char ChaZhi = 'a' - 'A';
    int num_Kong = 0;
    int j = 0, k = 0;
    int new_len = 0;
    memset(ret_sp, 0, n + 1);

    for (i = 0; i < n; i++) {
        if (s[i] != ' ') {
            if (s[i] >= 'a' && s[i] <= 'z') {
                s[i] = s[i] - ChaZhi;
            } else {
                s[i] = s[i] + ChaZhi;
            }
        } else {
            num_Kong++;
        }
    }

    if (num_Kong == 0) {
        memcpy(ret_sp, s, n);
        return ret_sp;
    }


    for (i = n - 1; i >= 0; i--) {

        if (s[i] != ' ') { //非空格
            j++;
            if (i == 0) {

                memcpy(&ret_sp[new_len], &s[i], j);
                new_len = new_len + j;
            }
            continue;
        } else { //找到空格

            memcpy(&ret_sp[new_len], &s[i+1], j);

            new_len = new_len + j;
            ret_sp[new_len] = ' ';
            new_len = new_len + 1;
            j = 0;
        }

    }

    return ret_sp;
}
发表于 2025-05-23 15:35:28 回复(0)
一道题只能提交一次评论吗
char result[1000001] = " ";

char* trans(char* s, int n ) {
    int j = n - 1;//每个单词的最后一个字母下标
    int k = 0;//新字符串每次存放一个单词时的首地址
    for (int i = n - 1; i >= -1; i--)
    {
        if (s[i] == ' ' || i == -1)
        {
            memcpy(&result[k], &s[i+1], j - i);//j-i是单词长度
            if (i != -1)
            {
                result[k+j] = ' ';   //在单词后面自动存放一个空格
            }
            k = k + (j - i) + 1;
            j = i - 1;
        }
        else{
            continue;
        }
    }

    for (int i = 0; i < n; i++)
    {
        if (result[i] >= 'a' && result[i] <='z')
        result[i] = result[i] - ('a' - 'A');
        else if (result[i] >= 'A' && result[i] <='Z')
        result[i] = result[i] + ('a' - 'A');
        else if (result[i] == '\0')
        result[i] = ' ';
        else ;
    }
    return result;
}


发表于 2024-03-14 00:59:10 回复(1)
#include <string.h>
char* trans(char* s, int n ) {
    char* out;
    int now_n,last_n;
    out = (char*) malloc(n+10);
    now_n = n;
           
    while(now_n)
    {
        last_n = now_n;
        while(s[now_n-1]!=' ')
        {
            now_n--;
            if(now_n <= 0)
                break;
        }
        if(s[now_n-1]==' ')
            out[n-now_n] = ' ';
               
        {
            int i;
            for(i=0;i<last_n-now_n;i++)
            {
                if(s[now_n+i]<='Z')
                    out[n-last_n+i] = s[now_n+i]+('a'-'A');
                else
                    out[n-last_n+i] = s[now_n+i]-('a'-'A');
            }
        }
        now_n--;
         
        if(now_n <= 0)
        {    
            out[n] = '\0';
            break;
        }
    }
    return out;
}

编辑于 2024-03-13 15:30:26 回复(0)
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param s string字符串
 * @param n int整型
 * @return string字符串
 */
#include <ctype.h>
#include <stdlib.h>
//大小写转换
char* roll(char* s) {
    for (int i = 0; s[i]!='\0'; i++) {
        if (s[i] >= 'A' && s[i] <= 'Z') {
            s[i] = tolower(s[i]);//s[i]=s[i]+32,利用ascii码进行大小写转化
        } else if (s[i] >= 'a' && s[i] <= 'z') {
            s[i] = toupper(s[i]);//s[i]=s[i]-32
        }
    }
    return s;
}
char* swap(char* s,int start,int end){
    while (start<end) {
        char temp=s[start];
        s[start]=s[end];
        s[end]=temp;
        start++;
        end--;
    }
    return s;
}
char* trans(char* s, int n ) {
    // write code here
    roll(s);
    swap(s, 0, n-1);
    int start=0;
    for (int i=0; i<=n; i++) {
        if (s[i]==' '||s[i]=='\0') {
            swap(s, start, i-1);
            start=i+1;
        }
    }
    return s;
}

编辑于 2024-03-12 14:43:39 回复(0)
先转换大小写,再整体反转,再单个反转

发表于 2023-12-27 18:36:01 回复(0)
C语言双n写法
#include <stdlib.h>

char* trans(char* s, int length ) {

    int index = 0;
    char* result = (char*)malloc((length + 1) * sizeof(char));

    for (int left = length - 1, right = length - 1; left >= 0; right = left) {

        if (s[left] == ' ') {
            result[index++] = s[left--];
            continue;
        }

        while (left >= 0 && s[left] != ' ') {
            left--;
        }

        for (int middle = left + 1; middle <= right; middle++) {
            if (s[middle] <= 'Z') {
                result[index++] = s[middle] + 32;
            } else {
                result[index++] = s[middle] - 32;
            }
        }

    }

    result[length] = '\0';
    return result;

}


发表于 2023-10-31 14:15:21 回复(0)
要是用字符串函数要简单得多我只会用笨办法
#define COUNT ('a'-'A')
char* trans(char* s, int n ) {
    // write code here
    //记录长度
    int m=n;
    //进行整体大小写转换
    while(n--)
    {
        if(s[n]>='A'&&s[n]<='Z')
        {
            s[n]+=COUNT;
        }
        else if(s[n]>='a'&&s[n]<='z')
        {
            s[n]-=COUNT;
        }
    }

    //定义指针p指向字符串末尾
    char *p=&s[m];
    //定义一个数字来保存反转后的字符串
    //开个动态空间可直接返回new,否则还得把new的内容返回给s
    char new[m];
    //flag用来存储s中每段已空格分开的字符长度,包含空格
    int flag=0;
    //newflag用来记录new光标的位置
    int newflag=0;
    //定义指针ptr来指向每小段字符串
    char*ptr;

    //从s字符串末尾开始遍历,直到超出地址界限
    while(p!=s-1)
    {
        p--;
        flag++;
        //碰到空格
        if(*p==' ')
        {
            //ptr+1才指向每小段字符串第一个字符,否则包含空格
            ptr=p+1; 
            //将小段字符串存入new 
            for(int i=0;i<flag-1;i++)
            {
                new[newflag+i]=*(ptr++);

            }
            //更新new光标
            newflag+=flag;
            //给new数组的小段字符串补空格
            new[newflag-1]=' ';
            //小段字符串长度清零
            flag=0;     
        }
        //已指向s字符串开头
        else if(p==s)
        {
            //此时无空格
            ptr=p;
            //将第一段小段字符串存入new 
            for(int i=0;i<flag;i++)
            {
                new[newflag+i]=*(ptr++);
            }
            //更新new光标
            newflag+=flag;
            //补字符串结束标志,防止打出多余数据
            new[newflag]='\0';
            //小段字符串长度清零
            flag=0; 
        }
        
    }
    //把new的内容返回给s
    for(int i=0;i<m;i++)
    {
        s[i]=new[i];
    }

    return s;
}


改了一下,结果过不了,n==0,让他直接返回,整的啥奇奇怪怪的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define COUNT ('a'-'A')

void reserve(char*s,int n)
{
    //进行整体大小写转换
    while(n--)
    {
        if(s[n]>='A'&&s[n]<='Z')
        {
            s[n]+=COUNT;
        }
        else if(s[n]>='a'&&s[n]<='z')
        {
            s[n]-=COUNT;
        }
    }
}

char* trans(char* s, int n ) {
    // write code here
    if(n>100000||n==0)
    {
        return s;
    }
    printf("n=%d\n",n);
     reserve(s,n);

    char*p=&s[n];
    int len=0;
    int flag=0;
    char*newstr=malloc((n+1)*sizeof(char));
    while(p!=s-1)
    {
        p--;
        len++;
        if(*p==' ')
        {
            strncpy(newstr+flag,p+1,len-1);
            flag+=len;
            *(newstr+(flag-1))=' ';
            len=0;
        }
        else if(p==s)
        {
            strncpy(newstr+flag,p,len);
            flag+=len;
            *(newstr+(flag))='\0';
            len=0;
            
        }
        //return newstr;
    }
    return newstr;
}


发表于 2023-09-14 16:45:56 回复(0)
我的方法是采取双指针的算法,先从倒序遍历原数组,找到第一个空格字符,然后将左指针赋值为空格后一个字符,右指针则是最后一个字符或者是上一个空格字符的前一个字符。然后将左右指针之间的字符转换大小写,并赋值给新的字符数组。

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param s string字符串 
 * @param n int整型 
 * @return string字符串
 */
#include <stdlib.h>
char charUpDown(char c)
{
    if(c >= 'a' && c <= 'z')
    {
        c -= 32;
    }
    else if (c >= 'A' && c <= 'Z') {
        c += 32;
    }
    else {
    
    }
    return c;
}

char* trans(char* s, int n ) {
    // write code here
    char *arr = malloc((n+1)*sizeof(char));
    int left, right, index, i, j;
    left = right = n-1;
    i = j = index = 0;
    while(1)
    {
        while(left >=0 && s[left] != ' ')
        {
            left--;
        }
        i = left + 1;
        j = right;
        for( ; i <= j; i++)
        {
            arr[index++] = charUpDown(s[i]);
        }
        if(left >= 0)
        {
            arr[index++] = s[left];
            left--;
            right = left;
        }
        else {
            arr[index] = '\0';
            break;
        }
    }
    return arr;
}


发表于 2023-09-10 21:34:56 回复(0)
char* trans(char* s, int n ) {
    // write code here
    char* a=(char*)malloc(sizeof(char)*n*2);
    int i=0;
    //数组每个单词逆序
    while(i<n)
    {
        int key=i;
        int cnt=0;
        while(s[i]!=' '&&s[i]!='\0')
        {
            cnt++;
            i++;
        }
        int left=key;
        int right=key+cnt-1;
        while(left<right)
        {
            int temp;
            temp=s[left];
            s[left]=s[right];
            s[right]=temp;
            left++;
            right--;
        }
        i++;
    }
    //数组大小写转换
    int j;
    for(j=0;j<n;j++)
    {
        if(s[j]>='a'&&s[j]<='z')
        {
            s[j]=s[j]-32;
        }
        else if(s[j]>='A'&&s[j]<='Z')
        {
            s[j]=s[j]+32;
        }

        a[n-1-j]=s[j];
    }
    return a;
}
发表于 2023-08-17 19:34:55 回复(0)
/**
 *
 * @param s string字符串
 * @param n int整型
 * @return string字符串
 * @param time 统计连续字符的个数
 * @param i,j 计数器
 */
#include <stdio.h>
char* trans(char* s, int n ) {
    int  i, j = 0, time = 0;
    char temp;
    // write code here
    for (i = 0; i <= ((n - 1) >> 1); i++) {
        if (s[i] >= 'A' && s[i] <= 'Z') s[i] = s[i] + 32;
        else if (s[i] >= 'a' && s[i] <= 'z') s[i] = s[i] - 32;
        if (i != n - 1 - i) {
            if (s[n - 1 - i] >= 'A' &&
                    s[n - 1 - i] <= 'Z') s[n - 1 - i] = s[n - 1 - i] + 32;
            else if (s[n - 1 - i] >= 'a' &&
                     s[n - 1 - i] <= 'z') s[n - 1 - i] = s[n - 1 - i] - 32;
            temp = s[i];
            s[i] = s[n - 1 - i];
            s[n - 1 - i] = temp;
        }
    }//首尾互换+改变大小字母
    while (j < n) {
        if (s[j] == ' ' || j == n - 1) {
            i = j;
            if (j == n - 1) {
                i = j + 1;
                if (time > 1)
                    time++;
            }
            while (time > 0) {
                temp = s[i - time];
                s[i - time] = s[i - 1];
                s[i - 1] = temp;
                i--;
                time = time - 2;
            }//交换两个不连续空格内的字符
            while (s[j + 1] == ' ') {
                j++;
            }//跳过连续的空格
            j++;
            time = 0;
        }
        j++;
        time++;
    }
    return s;
}



发表于 2023-03-28 19:19:16 回复(0)
绕了些弯
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void swap(char* a, char* b) {
	char t;
	t = *a;
	*a = *b;
	*b = t;
}

char* reverse(char* s, int len) {
	int i = 0;
	int l=0;
	int  *ret = (int*)malloc(sizeof(int) * (len + 1));

	while (i < len/2) {		//全部翻转
		swap(&s[i], &s[len-1-i]);
		i++; 
	}
	i = 0;

	while (i < len) {		//改变大小写
		if (s[i] <= 'z' && s[i] >= 'a') {
			s[i] = s[i] - 32;
		}
		else if (s[i] <= 'Z' && s[i] >= 'A') {
			s[i] = s[i] + 32;
		}
		i++;
	}
	int j = 0;
	i = 0;		
	while (i< len) {		//记录空格的下标
		if (s[i] == ' ') {
			ret[j] = i;
			j++;
		}
		i++;
	}

	int jj = j;
	j = 0;
	int t=0;
	l = ret[j];
	int a = 0;
	t = l;
	if (jj > 0) {//防止字符串中没有空格
		for (i = 0; i < len; i++) {//实现单个字母翻转
			if (s[i] == ' ') {
				a = l; j++;	
				if (j >= jj)ret[j] = len;//最后一个空格
				l = ret[j];
				t = l; 
				if (s[i + 1] != ' ') i++;//防止多个空格出现

			}

			if (i < a + (l - a) / 2 + 1) {	//单词翻转
				if (i < t - 1) {
					swap(&s[i], &s[t - 1]);
					t--;
				}
			}
		}
	}
	else {//没有空格字符串
		i = 0;
		while (i < len / 2) {		//全部翻转
			swap(&s[i], &s[len - 1 - i]);
			i++;
		}
	}
	free(ret);
	return s;
}

int main() {

	int len = 16;
	char s[17]= "now        Coder";
	reverse(s, len);//字符串翻转且改变大小写
	puts(s);
	return 0;
}

发表于 2023-03-09 14:32:38 回复(0)
char* trans(char* s, int n ) {
    // write code here
    
    int space_number=0;/*记录空格的数量*/
    int sub_len=0;/*记录每一个子字符串的长度*/
    char *str_src_2=0;/*保存原字符串*/
    char *str_src=s;/*保存原字符串*/
    char *space_point;/*用于保存空格的地址*/
    char **space_index;/*保存空格地址*/
    char **space_index_2;/*保存空格地址*/
…        memcpy(return_str,str_src_2,sub_len);    
    }
    return return_str_2;
}

发表于 2023-02-04 20:20:29 回复(0)
#include <ctype.h>
void reverse(char* start, char* destination)
{
    while(start<destination)
    {
        char tmp=*start;
        *start=*destination;
        *destination=tmp;
        start++;
        destination--;
    }
}
char* trans(char* s, int n ) 
{
    reverse(s,s+n-1);
    int i=0;
    char* start=s;
    for (i=0;i<n;i++)
    {
        if (islower(*(s+i)))
            *(s+i)=toupper(*(s+i));
        else if (isupper(*(s+i)))
            *(s+i)=tolower(*(s+i));

        if (*(s+i)==' '&&*(s+i-1)!=' ')
        {
            reverse(start,s+i-1);
        }
        else if (*(s+i-1)==' '&&*(s+i)!=' ')
        {
            start=s+i;
        }
    }
    if (*(s+i-1)!=' ')
        reverse(start,s+i-1);
    return s;
}

发表于 2023-01-12 09:52:07 回复(0)

思路就是使用2个指针,从结尾开始遍历,找到非空格的字符串段,写入新串中,空格直接写入,直到头

char* trans(char* s, int n ) {
    // write code here
    if(n==0) return NULL;
    char* ret = (char*)malloc(sizeof(char)*(n+1));
    if(ret==NULL) return NULL;
    int head=n-1, tail=head, retLoc=0;
    while(tail>=0) {
        if(s[head]!=' ' && head>-1) head--;
        else {
            head++;
            for(int j=head; j<=tail; j++) {
                ret[retLoc]=s[j];
                if(ret[retLoc]>='a'&& ret[retLoc]<='z') ret[retLoc]-=32;
                else if(ret[retLoc]>='A'&& ret[retLoc]<='Z') ret[retLoc]+=32;
                printf("%c",ret[retLoc]);
                retLoc++;
            }
            if(head==0) {
                tail=head;
                break;
            }
            head--;
            while(s[head]==' '){
                ret[retLoc++]=' ';
                head--;
            }
            tail=head;
        }
    }
    ret[n]='\0';
    return ret;
}
发表于 2022-11-15 16:59:34 回复(0)

问题信息

难度:
26条回答 19971浏览

热门推荐

通过挑战的用户

查看代码
字符串变形