首页 > 试题广场 >

算法基础-字符移位

[编程题]算法基础-字符移位
  • 热度指数:36963 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?



输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.



输出描述:

对于每组数据,输出移位后的字符串。

示例1

输入

AkleBiCeilD

输出

kleieilABCD
常数级空间复杂度就行,交换移动元素使用位操作的那个版本swap(),进一步节省空间
#include<iostream>
#include<string>
using namespace std;

bool isCap(char c)
{
    if (c >= 'A' && c <= 'Z')
        return true;
    else
        return false;
}
 
void mSwap(char &a, char &b)
{
    if (a != b)
    {
        a ^= b;
        b ^= a;
        a ^= b;
    } 
}
 
int main()
{
    string s;
    while (cin >> s)
    {
        int len = s.size();
        int end = len;
        for (int i = 0; i<end; ++i)
        {
            if (isCap(s[i]))
            {
                int j = i;
                for (; j<len- 1; ++j)
                    mSwap(s[j], s[j + 1]);
                --end;
                --i;
            }
        }
        cout << s <<endl;
    }
    return 0;
}

编辑于 2016-09-10 23:03:14 回复(15)
用STL的partition算法直接搞定
#include<iostream>
#include<algorithm>
using namespace std;
 
bool isLower(charc) {
    returnc>='a';
}
 
intmain() {
    string s;
    while(cin >> s) {
        stable_partition(s.begin(),s.end(),isLower);
        cout << s << endl;
    }
}

发表于 2016-06-16 14:51:00 回复(16)
#短小精悍
def fun(l):
    l = list(l)
    i = 0
    count = 0
    while count < len(l):
        if l[i].isupper():
            l.append(l.pop(i))
        else:
            i += 1
        count += 1
    return reduce(lambda x,y: x+y,l)

发表于 2017-08-05 23:29:04 回复(3)
importjava.util.*;
 
publicclassMain {
    publicstaticvoidmain(String[] args) {
        Scanner sc = newScanner(System.in);
 
        while(sc.hasNext()) {
            StringBuffer sb = newStringBuffer(sc.nextLine());
            inttimes = 0;
 
            for(inti = 0; i < sb.length() - times; i++) {
                if(Character.isLowerCase(sb.charAt(i)))
                    continue;
                sb.append(sb.charAt(i));
                sb.delete(i, i + 1);
                times++;
                i--;
            }
            System.out.println(sb);
        }
    }
}
发表于 2016-06-04 14:39:31 回复(7)
我的输出在OJ上跑大小写分界的地方有个换行,我在本地跑根本没有这个换行,输出结果和提供的结果一致,这个换行到底是哪来的?
基本思路就是从后往前遍历碰到大写字母就跟后面的交换,直到遇到大写字母为止,然后再往前遍历。。。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string data;
while (getline(cin, data))
{
int count = data.size();
for (int index = count - 1; index >= 0; index--)
{
if (data[index] >= 'A' && data[index] <= 'Z')
{
for (int tmp = index; tmp<count - 1; tmp++)
{
if (data[tmp + 1] >= 'A' && data[tmp + 1] <= 'Z')
{
break;
}
swap(data[tmp], data[tmp + 1]);
}
}
}


cout << data << endl;
data.clear();
}


return 0;
}
发表于 2016-07-02 11:22:35 回复(5)
import sys
import re  
for line in sys.stdin:
    s1 = line.strip()
    print(re.sub(r'[A-Z]','',s1) + re.sub(r'[a-z]','',s1))

编辑于 2018-04-04 14:32:47 回复(1)
PHP的有木有,冒泡排序思想。
<?php
while($str = trim(fgets(STDIN))){
    for($i =0; $i < strlen($str); $i++){
        $flag =true;
        for($j =0; $j < strlen($str)-1; $j++){
            if($str[$j]>='A'&& $str[$j]<='Z'&& ($str[$j+1]>'Z'|| $str[$j+1]<'A')){
                $temp = $str[$j];
                $str[$j] = $str[$j+1];
                $str[$j+1] = $temp;
                $flag =false;
            } 
        }
        if($flag){
            break;
        }
    }
    echo $str.PHP_EOL;
}
发表于 2017-09-07 14:03:08 回复(0)
#include<iostream>
#include<string>
using namespace std;
int main()
{string str;
while(cin>>str)
{
int len=str.size();
for(int i=0,count=0;i<len,count<len;i++,count++)
{
if(str[i]>='A'&&str[i]<='Z')
{
char w=str[i];
for(int j=i+1;j<len;j++)
str[j-1]=str[j];
str[len-1]=w;
i=i-1;
}
}
cout<<str<<endl;
}
}
编辑于 2016-08-30 10:28:57 回复(7)

import java.util.Scanner;

/**
 * Created by 10648 on 2017/2/22 0022.
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String string = scanner.nextLine();
            char [] chars = string.toCharArray();
            int length = string.length();
            for (int i = 0; i < length; i ++) {
                for (int j = 1; j < length - i; j ++) {
                    if ((chars[j-1] >= 'A' && chars[j-1] <= 'Z') &&
                            (chars[j] < 'A' || chars[j] > 'Z')) {
                        char temp = chars[j-1];
                        chars[j-1] = chars[j];
                        chars[j] = temp;
                    }
                }
            }
            System.out.println(String.valueOf(chars));
        }
    }
}
编辑于 2017-02-22 18:53:30 回复(1)
#include <iostream>
#include <string>
using namespace std;
 
int main() {
    string s;
    while (cin >> s) {
        int n = s.size();
        int p = n;
        for (int i = 0;i < p;++i) {
            if (s[i] >= 'A' && s[i] <= 'Z') {
                char t = s[i];
                int j = i;
                for (;j < n-1;++j) {
                    s[j] = s[j + 1];
                }
                s[j] = t;
                --p;
                --i;
            }
        }
        cout << s << endl;
    }
 
    return 0;
}

发表于 2016-05-19 20:33:52 回复(4)
#include<iostream>
#include<string>
#include<algorithm> 
using namespace std;
int main()
{
	string	A;
	while(cin>>A)
	{
		int length = A.size();
		for(int i = length-2;i>=0;i--)
		{
		for(int j = i;(i<length) &&( (A[j]>='A'&&A[j]<='Z') && 
                                         (A[j+1]>='a' && A[j+1]<='z'));j++)
				     swap(A[j],A[j+1]);
		}
		cout<<A<<endl;		
	}
	return 0;
}
生生当成倒着的插入排序,只是插入条件改变,前大后小就交换直到尾部。
编辑于 2016-10-09 20:09:48 回复(0)
#include <iostream>
#include <string.h>
using namespace std;
int main(){
	string s;
	while(cin >> s){
		if(s.length() >= 1 && s.length() <= 1000){
			for(int i = 0; i < s.length(); i++)
				if(s[i] >= 'a' && s[i] <= 'z')
					cout << s[i];
			for(int i = 0; i < s.length(); i++)
				if(s[i] <= 'Z' && s[i] >= 'A')
					cout << s[i];
			cout << endl;//开始没写这个老是通不过...
		}
	}
	return 0;
}
根据题意输出了正确结果...
这个题仔细看看答案- -把大小写分开输出就可以了。
第一次做对腾讯的题,好鸡冻2333.


发表于 2016-06-07 20:26:55 回复(80)
//java解法,不需要额外空间,用两个游标,一个表示当前处理元素,一个表示下一个待放置小写字母的位置,每次处理将中间的所有大写字母移动一遍

import java.util.*;
public class Main {
public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()){
            String s = sc.nextLine();
            int len = s.length();
            char[] c = s.toCharArray();
            int p = 0;
            char tmp;
            for ( int i = 0; i < len; i++){
                if (c[i] > 'Z'){
                for (int j = p; j < i; j++){
                   tmp = c[i];
                   c[i] = c[j];
                   c[j] = tmp;
                }
                p++;
                }
            }
            System.out.println(new String(c));
        }
    }
}
发表于 2017-04-08 21:06:32 回复(3)

C++模拟

类似冒泡排序

  • 若是大写字母,不进行操作
  • 若是小写字母,则将该小写字母移动到其之前的所有大写字母之前
#include <bits/stdc++.h>

using namespace std;

int main() {
    string s;
    while (cin >> s) {
        int n = s.size();
        for (int i = 1; i < n; ++i) {
            if (isupper(s[i])) continue;    // 大写字母,不进行操作
            for (int j = i - 1; j >= 0; --j) {    // 小写字母,移动到其之前的所有大写字母之前
                if (isupper(s[j])) swap(s[j], s[j + 1]);
            }
        }
        cout << s << endl;
    }
    return 0;
}
发表于 2022-08-20 11:28:32 回复(0)
先输出小写,再输出大写,原来这么简单......
#include <stdio.h>
#include <string.h>

#define MAX_LEN 1000

int main() {
    char str[MAX_LEN];
    while (gets(str)) {
        int len = strlen(str);
        for (int i = 0; i < len; ++i) {
            if (str[i] >= 97 && str[i] <= 122) {
                printf("%c", str[i]);
            }
        }
        for (int i = 0; i < len; ++i) {
            if (str[i] >= 65 && str[i] <= 90) {
                printf("%c", str[i]);
            }
        }
        printf("\n");
    }
    return 0;
}


发表于 2021-04-15 22:12:12 回复(0)
遍历字符串两遍,第一次只打印小写字母,第二次只打印大写字母;或者无视空间复杂度的要求,用空间换时间,遍历一遍获得小写字母串和大写字母串,最后拼接打印。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while((str = br.readLine()) != null) {
            for(int i = 0; i < str.length(); i++)
                if(str.charAt(i) >= 97 && str.charAt(i) <= 122) System.out.print(str.charAt(i));
            for(int i = 0; i < str.length(); i++)
                if(str.charAt(i) >= 65 && str.charAt(i) <= 90) System.out.print(str.charAt(i));
            System.out.println();
        }
    }
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while((str = br.readLine()) != null) {
            StringBuilder upper = new StringBuilder();
            StringBuilder lower = new StringBuilder();
            for(int i = 0; i < str.length(); i++) {
                if(str.charAt(i) >= 97 && str.charAt(i) <= 122) lower.append(str.charAt(i));
                if(str.charAt(i) >= 65 && str.charAt(i) <= 90) upper.append(str.charAt(i));
            }
            System.out.println(lower.toString() + upper.toString());
        }
    }
}


编辑于 2021-02-08 15:41:07 回复(0)
    public  String getResult(String str){
        char[] c = str.toCharArray();
        int index = 0;
        int big = 0;
        while (big<c.length&&index<c.length){
            if (isSmall(c[index])){        //说明碰到小写字母了
                if(big<index){  //说明之前有big出现
                    if (isSmall(c[big+1])){ //big的下一个是小写字母 那么我们可以直接交换
                        char temp = c[big];
                        c[big] = c[index];
                        c[index] = temp;
                        big = index;
                    }else {     //big的下一个还是big 如果贸然交换 相对顺序就变了 所以我们要插入排序
                        char value = c[index];
                        while (index>big){
                            c[index] = c[index-1];
                            index--;
                        }
                        c[index] = value;
                        big = big+1;
                    }
                }else { //这种情况说明之前还没有big出现
                    big++;
                }
            }
            index++;
        }
        return String.valueOf(c);
    }

发表于 2020-04-22 16:37:43 回复(0)
双指针+冒泡思想+从后向前遍历
遇到大写字母j指针左移动,i指针每轮都移动
当i<j且i位置的字符大写时对i到j范围内的字符进行冒泡排序
#include<iostream>
(720)#include<string>
using namespace std;
int main(){
    string str;
    while(cin>>str){
        for(int i=str.size()-1,j=str.size()-1;i>=0;i--){
            int flag=isupper(str[i]);
            if(flag&&i<j){
                for(int k=i;k<j;k++){
                    swap(str[k],str[k+1]);
                } 
            } 
            if(flag) j--;
        }
        cout<<str<<endl;
    }
    return 0;
}


编辑于 2020-03-20 11:52:03 回复(0)
在DEV上运行成功了,在这上边为什么没有输出?就不懂了。
发表于 2019-04-06 21:09:10 回复(0)
#include <iostream>
#include <string>
#include <algorithm>
usingnamespacestd;
 
intmain()
{
    string s;
    while(cin >> s)
    {
        intcount = 0;
        intindex = 0;
 
        for(inti = 0; i < s.size(); i++)
        {
            if(s[i] >='A'&& s[i] <='Z')
            {
                count++;
            }
            else
            {
                chartemp = s[i];
                intk = i;
                for(intj = 0; j < count; j++)
                {
                    s[k] = s[k - 1];
                    k--;
                }
                s[index] = temp;
                index++;
            }
        }
 
        cout << s << endl;
    }
}

组合冒泡啊。。
虽然通过了但不知道符不符合题目的要求。。
发表于 2019-04-04 11:27:18 回复(0)

问题信息

难度:
272条回答 43800浏览

热门推荐

通过挑战的用户