首页 > 试题广场 >

字符串变形

[编程题]字符串变形
  • 热度指数:133389 时间限制: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"
import java.util.*;

public class Solution {
    public String trans(String s, int n) {
        StringBuilder spaceR = new StringBuilder();
        String[] sList = s.split(" ");
        reverse(sList);
        int j = s.length()-1;
        while (j >= 0 && s.charAt(j) == ' ') {
            spaceR.append(" ");
            j--;
        }
        StringBuilder sNew = new StringBuilder();
        sNew.append(spaceR.toString());
        for (int i = 0;i < sList.length;i++) {
            if (i == sList.length-1) {
                sNew.append(sList[i]);
                continue;
            }
            sNew.append(sList[i] + " ");
        }

        return sNew.toString();
    }
    
    public void reverse(String[] sList) {
        int left = 0;
        int mid = sList.length / 2;
        int j = sList.length - 1;
        for (int i = 0;i < mid;i++) {
            String tmp = sList[i];
            sList[i] = lowUpper(sList[j]);
            sList[j] = lowUpper(tmp);
            j--;
        }
        if (sList.length % 2 != 0) {
            sList[j] = lowUpper(sList[j]);
        }
    }
    
    public String lowUpper(String s) {
        StringBuilder sNew = new StringBuilder();
        for (int i = 0;i < s.length();i++) {
            int tmp = s.charAt(i);
            if (tmp >= 97 && tmp <= 122) {
                tmp -= 32;
            }else if (tmp >= 65 && tmp <= 90){
                tmp += 32;
            }
            sNew.append((char) tmp);
        }
        return sNew.toString();
    }
}

发表于 2021-01-17 20:44:16 回复(0)
不要用split 。空格问题不好弄清,前后中间可能都有多个空格

import java.util.*;
//不要用split 空格问题会坑死自己
public class Solution {
    public String trans(String s, int n) {
        String res = "";
        String tempStr = "";
        for(int i = 0; i < n; i++){
            char c = s.charAt(i);
            if(c>='a'&& c<='z')
                tempStr += Character.toUpperCase(c);
            else if(c>='A'&& c<='Z')
                tempStr += Character.toLowerCase(c);
            else{
                tempStr = c+tempStr;
                res = tempStr + res;
                tempStr="";
            }
        }
        res = tempStr+res;
        return res;
    }
}


发表于 2020-02-13 01:34:51 回复(9)
问题本身不难,但是使用split进行字符串切分的时候需要注意一下。

因为我们需要每一个空格进行一次切分,所以,这里设置limit为-1。

import java.util.*;

public class Solution {
    
    // 反转字符串大小写
    public String reverse(String str){
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0; i < str.length(); i++){
            if(Character.isUpperCase(str.charAt(i))){
                stringBuilder.append(Character.toLowerCase(str.charAt(i)));
            }else{
                stringBuilder.append(Character.toUpperCase(str.charAt(i)));
            }
        }
        return stringBuilder.toString();
    }
    
    public String trans(String s, int n) {
        // write code here
        String[] tmp = s.split(" ", -1);// 这里,limit设置为-1,模式可以应用无数次
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = tmp.length - 1; i >= 0; i--){
            stringBuilder.append(reverse(tmp[i]));
            if(i != 0){
                stringBuilder.append(" ");
            }
        }
        return stringBuilder.toString();
    }
}


编辑于 2020-09-28 22:56:18 回复(4)
最简单的解法
public class Solution {
    public String trans(String s, int n) {
        // 本题实际就是把字符串s反转(单词中的字符位置不反转),遇到空格不变,遇到大写字母变成小写,小写字母变成大写
        StringBuffer res = new StringBuffer(); // 存放最终结果
        int index = 0; // 记录字母应插入的位置
        for (int i = n - 1; i >= 0; i--) {
            char ch = s.charAt(i);
            if (ch == ' ') {
                res.append(" ");
                index = res.length();
            } else {
                // 当前字符是字母
                if (ch >= 'A' && ch <= 'Z') {
                    res.insert(index, (char)(ch + 32)); // 大写字母变为小写,每次都插在index位置
                } else {
                    res.insert(index, (char)(ch - 32)); // 小写字母变为大写,每次都插在index位置
                }
            }
        }
        return res.toString();
    }
}


发表于 2021-08-26 16:31:21 回复(2)
class Solution:
    def trans(self , s: str, n: int) -> str:
        # write code here
        s0=[]
        for i in s:
            if i!=' ':
                if i.islower():
                    s0.append(i.upper())
                else:
                    s0.append(i.lower())
            else:
                s0.append(' ')
        s0=''.join(s0).split(' ')
        return ' '.join(s0[::-1])

发表于 2022-01-05 10:12:59 回复(1)
function trans(s, n){
    return s
        .split(" ")
        .reverse()
        .join(" ")
        .replace(/([a-z]+)|([A-Z]+)/g, function(s, a, b){
          if(a){
                return a.toUpperCase();
          }
         if(b){
            return b.toLowerCase();    
          }
        });
}

module.exports = {
    trans : trans
}

没有人像我一样用一行代码解决的吗
发表于 2022-06-03 16:48:42 回复(0)
function trans(s, n){
        //write code here
    return s.split(" ").reverse().map(item => {
        return item.split('').map(str => {
            return str == str.toLowerCase()? str.toUpperCase():str.toLowerCase()
        }).join('')
    }).join(' ');
}

module.exports = {
    trans : trans
}

发表于 2022-03-14 19:50:04 回复(0)
class Solution {
public:
    string trans(string s, int n) {
        // 时间复杂度O(N),空间复杂度O(N)
        stack<string> stk;
        string tmp, res;
        for (char &c : s) {
            if (c >= 'a' && c <= 'z') tmp += c - 'a' + 'A';
            else if (c >= 'A' && c <= 'Z') tmp += c - 'A' + 'a';
            else {
                stk.push(tmp);
                stk.push(" ");
                tmp.clear();
            }
        }
        if (!tmp.empty()) stk.push(tmp);
        while (stk.size() != 1) {
            res += stk.top();
            stk.pop();
        }
        res += stk.top();
        return res;
    }
};

发表于 2022-10-19 17:22:10 回复(0)
/**
 *
 * @param s string字符串
 * @param n int整型
 * @return string字符串
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
static char transChar(char c) {//构建字符转换函数
    if (c <= 'Z' && c >= 'A')
        c += 32;
    else if (c <= 'z' && c >= 'a') {
        c -=  32;
        return c;
    }
    return c;//当都不满足条件时,返回原符号,本题即返回空格
}

char* trans(char* s, int n ) {
    int left = 0, right = 0;//双指针
    char* t = (char* )malloc(sizeof(char) * (n + 1));
    //构建n+1个符号长度的字符串t,多出来的一个是为了防止内存溢出,如果只分配n个符号,最后一个用例不会通过
    for (int i = 0; i < n; i++) t[i] = ' ';
    t[n] = '\0';
    //初始化字符串,全部赋值空格,方便输出
    if (s[0] == '\0') return "";
    for (int i = 0; i <= n; i++) {//从左至右遍历s
        if ( (s[right] == ' ' || s[right] == '\0') && right <= n  ) {
            //以空格为分隔,选出单个单词
            for (int i = 0; i < (right - left); i++) {
                t[n - right + i] = transChar(s[left + i]);
                //将left到right中间的单词子串转换并反转,从右到左赋给t,子串从左到右遍历
            }
            right ++;
            left = right;//左右指针同时右移,继续下一个单词取词

        } else
            right++;//当右指针不在空格时,右指针右移,左指针不动
    }
    return t;
    // write code here
}
发表于 2022-04-12 01:05:56 回复(0)
·  第一步先遍历字符串,并反转大小写。从前往后扫,如果遇到空格,就将单词反转。注意如果最后一个字符是空格就不用反转,否则直接反转。

·  第二步翻转整个字符串

class Solution {
public:
    void myReserve(string &s,int left,int right){
        if(left<0||right<0)
            return;
        while(left<right)
            std::swap(s[left++],s[right--]);
    }
    string trans(string s, int n) {
        // write code here
        int k ='a'-'A';
        int l=0,r=0;
        while(r<n){
            if(s[r]!=' '&&s[r]<'a')
                s[r]+=k;
            else if(s[r]!=' '&&s[r]>='a')
                s[r]-=k;
            
            if(r==n-1)
            {
                if(s[r]!=' ')
                    myReserve(s,l,r);
                break;
            }
            else if(s[r]==' ')
            {
                myReserve(s,l,r-1);
                l=r+1;
                r=l;
            }
            else
                r++;
        }
        myReserve(s, 0, n-1);
        return s;
    }
};
编辑于 2021-06-17 17:48:10 回复(0)
classSolution:
    def trans(self, s, n):
        # write code here
        t=""
        fori in s.swapcase().split(" ")[::-1]:
            t=t+i+" "
        returnt[:-1]
仅四行代码
发表于 2016-04-20 10:10:54 回复(0)
function trans(s, n) {
    //write code here
    return s.split(" ")
    .reverse()
    .map((item) => {
    return [...item].map((char) =>
        char == char.toLowerCase() ? char.toUpperCase() : char.toLowerCase()
    ).join('');
    }).join(' ');
}

发表于 2022-10-20 16:04:51 回复(0)
import java.util.Scanner;

public class TransString {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		while (scanner.hasNext()) {
			String s = scanner.nextLine();
			int n = scanner.nextInt();
			System.out.println(transString(n, s));
		}
	}

	public static String transString(int n, String s) {
		int flag = 0;
		if(s.charAt(s.length()-1) == ' '){
			flag = 1;
			s = s.substring(0, s.length()-1);
		}
		String[] strings = s.split(" ");
		StringBuffer tranBuffer = new StringBuffer();
		if(flag == 1){
			tranBuffer.append(" ");
		}
		for (int i = strings.length - 1; i >= 0; i--) {
			StringBuffer buffer = new StringBuffer(strings[i]);
			for (int j = 0; j < strings[i].length(); j++) {
				if (Character.isUpperCase(strings[i].charAt(j))) {
					buffer.setCharAt(j,
							Character.toLowerCase(strings[i].charAt(j)));
				} else {
					buffer.setCharAt(j,
							Character.toUpperCase(strings[i].charAt(j)));
				}
			}
			
			if (i != 0) {
				tranBuffer.append(buffer + " ");
			} else {
				tranBuffer.append(buffer);
			}
		}
		return tranBuffer.toString();
	}

}


发表于 2016-09-29 10:00:16 回复(1)
importjava.util.*;
 
publicclassSolution {
   publicString trans(String s, intn) {
        // write code here
        /*
        思路:1.将s按照单词分隔保存到字符串数组里面,并转为其大小写2.实现反序
        */
        String str[]=newString[n];
        String word="";
        intj=0;//代表单词个数
        inti;
        for(i=0;i<n;i++){
            charcurChar=s.charAt(i);
            if(s.charAt(i) == ' '){
                str[j++]=word;
                word="";
            }else{  
                 if(curChar>='a'&&  curChar <='z'){ //小写字母转为大写  
                    curChar=(char)(curChar-32);
                  }else{//大写字母转为小写
                     curChar=(char)(curChar+32);
                 } 
                word+=curChar;
            }          
        }
        str[j]=word;
       //反序
        for(i=0;i<(j+1)/2;i++){
            String tmp= str[i];           
            str[i]=str[j-i];
            str[j-i]=tmp;
        }
        String str1="";
        for(i=0;i<=j;i++){
            str1+=str[i];
            if(i !=j){
                str1+=" ";
            }
        }
        returnstr1;
    }
}

发表于 2016-04-20 22:00:14 回复(1)
class Solution {
public:
    string trans(string s, int n) {
        int begin = 0;
        int end = 0;
        for(int i=0;i<s.size();++i){
            tran_case(s[i]);
            if(s[i]==' '){
                string_swap(s, begin, i-1);
                begin = i +1;
            }
            if(i==s.size()-1){
                string_swap(s, begin, i);
            }
        }
        string_swap(s, 0, n-1);
        return s;
    }
private:
    void string_swap(string& str, int begin, int end){
        int mid = (end-begin-1)/2;
        for(int i=0;i<=mid;++i){
            swap(str[begin+i],str[end-i]);
        }
    }
    void tran_case(char& word){
        if(word>='a' && word<='z'){
            word = word + 'A' - 'a';
        }
        else if(word>='A' && word<='Z'){
            word = word + 'a' - 'A';
        }
        else{
            word = word;
        }
    }
};

发表于 2023-07-10 17:15:26 回复(0)
Java时空优解:字符串数组原地修改
作者:SoPlaying
链接:https://www.nowcoder.com/discuss/384816014410743808
来源:牛客网

import java.util.*;
 
public class Solution {
    // 字符串数组翻转函数
    public void reverseArr(char[] arr, int i, int j) {
        // 双指针左右滑动
        int left = i;
        int right = j;
        while(left<right) {
            char temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
     
    public String trans(String s, int n) {
        // 字符串数组原地修改
        char[] str = s.toCharArray();
        // 遍历更新:大写变小写、小写变大写、空值则不做处理
        for(int i=0; i<n; i++) {
            char element = str[i];
            if(element>='A' && element<='Z') str[i] = (char)(element-'A'+'a');
            else if(element>='a' && element<='z') str[i] = (char)(element-'a'+'A');
        }
        // 先整体翻转
        reverseArr(str, 0, n-1);
        // 此时每个单词也逆序了,需要根据空格将每个单元重新反转回去
        for(int i=0; i<n; i++) {
            if(str[i]==' ') continue;
            // 双指针,左指针的单词起始位置,右指针为单词末后一个位置
            int j=i;
            while(j<n && str[j]!=' ') j++;
            reverseArr(str, i, j-1); 
            i=j; // 更新左边界值
        }
        return new String(str);
    }
}


发表于 2022-08-04 21:22:27 回复(0)

这个代码为什么会超时呢?

class Solution {
public:
    string trans(string s, int n) {
        // write code here
        int p = 0;
        string ans;
        for (int i = 0; i < n; i++) {
            if (s[i] >= 'A' && s[i] <= 'Z') {
                s[i] += 32;
            } else if (s[i] >= 'a' && s[i] <= 'z') {
                s[i] -= 32;
            } else {
                ans = s.substr(p, i - p) + " " + ans;
                p = i + 1;
            }
        }
        ans = s.substr(p, n - p) + " " + ans;
        ans.erase(ans.size() - 1, 1);
        return ans;
    }
};
发表于 2022-04-24 09:05:23 回复(4)
位运算转换大小写:
char c='a'
c^=0x20;    //c=='A'
c^=0x20;    //c=='a'

发表于 2021-04-10 18:16:30 回复(0)
import java.util.*;

public class Solution {
   public String trans(String s, int n) {
        StringBuilder res = new StringBuilder("");
        StringBuilder sb = new StringBuilder("");
        for(int i=n-1;i>=0;i--){
            if(s.charAt(i)== ' '){
                res.append(sb.reverse()).append(" ");
                sb.setLength(0);
            }else {
                if (Character.isUpperCase(s.charAt(i))){
                    sb.append(Character.toLowerCase(s.charAt(i)));
                }
                if (Character.isLowerCase(s.charAt(i))){
                    sb.append(Character.toUpperCase(s.charAt(i)));
                }
            }
        }
        res.append(sb.reverse());
        return res.toString();
    }
}

发表于 2021-01-06 10:26:38 回复(0)
//题目不难 主要分为两步
//第一步是把字符串按照题目的要求翻转过来;
//第二步就是大小写互换;
class Solution {
public:
    string trans(string s, int n) {
        // write code here
        string res="",temp="";
        for(int i=0;i<n;i++){
            if(s[i]!=' ')temp+=s[i];
            else {
                res=' '+temp+res;
                temp.clear();
            }
        }
        if(!temp.empty())res=temp+res;
        //reverse(s.begin(),s.end());
        for(int i=0;i<n;i++){
            if(res[i]<='z'&&res[i]>='a')res[i]=toupper(res[i]);//小写变成大写
            else if(res[i]<='Z'&&res[i]>='A')res[i]=tolower(res[i]);//大写变成小写
        }
        return res;
    }
};


发表于 2020-02-18 20:37:21 回复(0)

问题信息

难度:
278条回答 17209浏览

热门推荐

通过挑战的用户

查看代码