对一个字符串里的字母倒序,别的字符保持原位不变?

时间:2022-09-06 10:55:04
有一个字符串,里面有字母,数字和标点,例如"1w4rt,5t7?9u"。要求把里面的字母按原来的顺序倒着排列,别的数字和标点不变,结果应该是"1u4tt,5r7?9w"。这是我面试时,面试人员问的一道问题,大家帮解决下

124 个解决方案

#1


我觉得可以用Regex.Split将字母提取出来,随后可以循环原字符串,是否和提取的字符串中的字符相同,若相同的第一个取提取出来的数组的对应倒序位置的字母

#2


有意思的题目,不知用正则方便不,考虑一下。

#3


把它存到字符数组中 提取字母 把字母顺序交换后 在重新写回数组 最后输出...

#4


当成字符数组用isAlpha进行判断,放入Hashtable,遍历并且做调换。

#5


using System;
using System.Text.RegularExpressions;

class Demo
{
  static string ReverseAlpha(string s)
  {
    string t = Regex.Replace(s, "[^A-Za-z]", "");
    char[] c = s.ToCharArray();
    for (int i = 0, j = t.Length - 1; i < c.Length; i++)
    {
      if (Char.IsLetter(c[i])) // c[i] >= 'A' && c[i] <= 'Z' || c[i] >= 'a' && c[i] <= 'z'
      {
        c[i] = t[j];
        j--;
      }
    }
    return new string(c);
  }

  static void Main()
  {
    string s = "1w4rt,5t7?9u";
    Console.WriteLine(s);
    string t = ReverseAlpha(s);
    Console.WriteLine(t);
  }
}

#6


        private string reverse(string src)
        {
            char[] s = src.ToCharArray();
            char c='\0';
            int i = 0;
            int j = s.Length - 1;
            for (; i < j; )
                if (s[i] >= 65 && s[i] <= 90 || s[i] >= 97 && s[i] <= 122)
                    if (s[j] >= 65 && s[j] <= 90 || s[j] >= 97 && s[j] <= 122)
                    { c = s[i]; s[i] = s[j]; s[j] = c; i++; j--; }
                    else
                        j--;
                else
                    if (s[j] >= 65 && s[j] <= 90 || s[j] >= 97 && s[j] <= 122)
                        i++;
                    else
                    { i++; j--; }
            return new string(s);
        }

#7


顶牛人!

#8


我汗

#9


#10


收藏

#11


该回复于2011-07-28 16:58:41被版主删除

#12


强~~

#13


学习了~~~

#14


学习一下

#15


就像快速排序里一样,一个指头,一个指尾,都往中间走,遇到字母就停下来,两个都停时就换,直到指针都指到一起去
大概就是5楼的程序

#16


不是很難啊

#17


按6L的思想用C++编写运行了,学习了。

#18


有点意思

#19


说实话用正则我佩服..

其他的就算了``  

#20


前几天去某个公司面试也遇到类似的问题,现用c++写了个简单的
#include <stdio.h>
#include <string.h>
//判读一个字符是否为字母,不区分大小写
bool isAlphabet(char ch)
{
  return ((ch >= 65 && ch <= 90)||(ch >= 97 && ch <= 122)); 
}
//从两头到中间找,然后替换
char* reverseStringByOrder(char * str)
{
int length=strlen(str);//字符串长度
int left=0,right=length-1;
while(left<right)
{
//跳过非字母
while(!isAlphabet(str[left]))
{
left++;
}
//跳过非字母
while(!isAlphabet(str[right]))
{
right--;
}
///////////交换两个字母
char temp=str[left];
str[left]=str[right];
str[right]=temp;
left++;
right--;
}
return str;
}
int main(int argc, char* argv[])
{
char test []="1w4rt,5t7?9u";
printf("the result:%s\n",reverseStringByOrder(test));
return 0;
}

#21


00

#22


//C/C++ 用交換法。
inline bool isalpha(char a){return (a>='a' && a<='z')||(a>='A' && a<='Z');}
inline void swap(char *a,char *b){char c = *b ; *b = *a ;  *a = c ; }
void ReverseAlpha(char *source)
{
  if(source == NULL)
    return ; 
  char *pb = source;
  char *pe = pb;
  while(*pe)++pe ;
  for(; *pb ; ++pb)
  {
    if(isalpha(*pb))
    {
      while(!isalpha(*pe)) --pe ;
      if(pb < pe)  //已交換完成
        swap(pb,pe--);
      else
        break;
    }
  }
}
int main(int argc, char* argv[])
{
    char *test = "1w4rt,5t7?9u";
    ReverseAlpha(test);  //1u4tt,5r7?9w
    printf("the result:%s\n",test);
    return 0;
}

#23


该回复于2014-10-04 09:52:25被版主删除

#24


顶一个

#25


顶,MARK

#26


字符数组

#27


用两个变量标记第一个和最后一个字母,交换完向中间推进,一直到碰头就完了嘛 

#28


用c++还可以,不过要思考一下。c#就不懂了

#29


堆栈法:
#include "stdio.h"

char Stack[20] = {0};
char *psBottom = Stack;
char *psTop = Stack;

char Input[20] = "1w4rt,5t7?9u";

void main()
{
char *pIndex = Input;

while (*pIndex != '\0')
{
if ((*pIndex >= 'a')&&(*pIndex <= 'z'))
{
*psTop = *pIndex;
psTop++;
}

pIndex++;

if (psTop > (psBottom + 20))
{
break;
}
}

pIndex = Input;

while (*pIndex != '\0')
{
if ((*pIndex >= 'a')&&(*pIndex <= 'z'))
{
if (psTop > psBottom)
{
psTop--;
*pIndex = *psTop;
}
}

pIndex++;
}

printf("%s\n",Input);
}

#30


20楼的程序特别的不错!支持!

#31


同意楼上的,风格很好,值得学习。
呵呵

#32


不错

#33


 急求:本人欲在傲游(Maxthon)浏览器的工具栏上安装一个自定义按钮,该按钮的功能是:当我按下该按钮时,启动d:\euro\hot.exe程序(该程序功能是:在当前网页中,搜索关键字,并将搜索结果及相关字段内容存入名为Asia2008.dbf数据库中,关闭当前网页)。请各位大侠指点做法,如有可能给出相关源程序,小生万分感谢!(Euro2000@126.com)

#34


我想 初始化一个数组都为零 长度等于字符串 遍历数组 把是字母的地方改为1,然后按着数组,把是1的地方的字目交换顺序

#35


ding

#36


很强大啊!

#37


up

#38


niu ,不错啊

#39


来学习一下了  

#40


                                 c
#include<stdio.h>
#include<string.h>
#define ISLETTER(t,i) ((t[i]>='a'&&t[i]<='z') || (t[i]>='A'&&t[i]<='Z'))
int main()
{
    char test[]="hello,the world !><abc;sample)((hit)(kill)(s))@#foolish#want r!+=";
    int i,j;
    char mid;
    printf("排序测试!\n");
    printf("原始数组: %s\n\n",test); 
    j=strlen(test)-1;
    printf("数组长度: %d\n",j+1); 
    for(i=0;i<=j;i++)
    {
       if( !ISLETTER(test,i) )
            continue;
        while( !ISLETTER(test,j) )
            j--;
        mid=test[i];
        test[i]=test[j];
        test[j]=mid;
        printf("%d 与 %d 互换\n",
        j--;
     }
     printf("排序后:   %s\n",test); 
     getch();
     return 0;
}

        
            
     

#41


很强啊,收藏了!

#42


第一感觉这就是个体力活!
用指针慢慢点吧

#43


回帖是一种美德!传说每天回帖即可获得 10 分可用分回帖是一种美德!传说每天回帖即可获得 10 分可用分

#44


收藏了,学习了一种好思路

#45


一个头指针,一个尾指针。

#46


20楼的方法比较好
应该前后同时找,左边找到的第n个和右边找到的第n个互换位置。这样就可以了。

#47


#include<stdio.h>

bool ischar(char pstr) //判读一个字符是否为字母,不区分大小写
{
if((pstr>=65)&&
(pstr<=90)||
(pstr>=97)&&
(pstr<=122))
return 1;
else
return 0;
}
char *reverse(char *str)//从两头到中间找,然后替换
{
char *left,*right,*tmp;

left=str;
        tmp=str;

        while(*tmp!='\0')
         tmp++;
        right=tmp-1;

while(left<right)
{
while(!ischar(*left))//跳过非字母
{left++;}

while(!ischar(*right))// 跳过非字母
{right++;}

char tmp=*left;/////////////交换两个字母
//str[left]=str[right];
*left=*right;
*right=*left;
*right=tmp;
left++;
right--;
}
return str;
}
void main()
{
char ch[]="a11b";
reverse(ch);
printf("%s\n",ch);
}

#48


手头没有工具
说下我的思路吧!
提取里面的每个字符保存起来,然后转换成int型 要加try、catch 用if判断不报错就保存 然后置换 ok

#49



void Reverse(char *p)
{
char  temp;
char *first = p;
char *end = p + strlen(p) - 1;
while(first < end)
{
while(!isalpha(*first))++first;
while(!isalpha(*end))--end;
temp = *first;
*first = *end;
*end = temp;
++first;
--end;
}
}

#50


学到了东西!

#1


我觉得可以用Regex.Split将字母提取出来,随后可以循环原字符串,是否和提取的字符串中的字符相同,若相同的第一个取提取出来的数组的对应倒序位置的字母

#2


有意思的题目,不知用正则方便不,考虑一下。

#3


把它存到字符数组中 提取字母 把字母顺序交换后 在重新写回数组 最后输出...

#4


当成字符数组用isAlpha进行判断,放入Hashtable,遍历并且做调换。

#5


using System;
using System.Text.RegularExpressions;

class Demo
{
  static string ReverseAlpha(string s)
  {
    string t = Regex.Replace(s, "[^A-Za-z]", "");
    char[] c = s.ToCharArray();
    for (int i = 0, j = t.Length - 1; i < c.Length; i++)
    {
      if (Char.IsLetter(c[i])) // c[i] >= 'A' && c[i] <= 'Z' || c[i] >= 'a' && c[i] <= 'z'
      {
        c[i] = t[j];
        j--;
      }
    }
    return new string(c);
  }

  static void Main()
  {
    string s = "1w4rt,5t7?9u";
    Console.WriteLine(s);
    string t = ReverseAlpha(s);
    Console.WriteLine(t);
  }
}

#6


        private string reverse(string src)
        {
            char[] s = src.ToCharArray();
            char c='\0';
            int i = 0;
            int j = s.Length - 1;
            for (; i < j; )
                if (s[i] >= 65 && s[i] <= 90 || s[i] >= 97 && s[i] <= 122)
                    if (s[j] >= 65 && s[j] <= 90 || s[j] >= 97 && s[j] <= 122)
                    { c = s[i]; s[i] = s[j]; s[j] = c; i++; j--; }
                    else
                        j--;
                else
                    if (s[j] >= 65 && s[j] <= 90 || s[j] >= 97 && s[j] <= 122)
                        i++;
                    else
                    { i++; j--; }
            return new string(s);
        }

#7


顶牛人!

#8


我汗

#9


#10


收藏

#11


该回复于2011-07-28 16:58:41被版主删除

#12


强~~

#13


学习了~~~

#14


学习一下

#15


就像快速排序里一样,一个指头,一个指尾,都往中间走,遇到字母就停下来,两个都停时就换,直到指针都指到一起去
大概就是5楼的程序

#16


不是很難啊

#17


按6L的思想用C++编写运行了,学习了。

#18


有点意思

#19


说实话用正则我佩服..

其他的就算了``  

#20


前几天去某个公司面试也遇到类似的问题,现用c++写了个简单的
#include <stdio.h>
#include <string.h>
//判读一个字符是否为字母,不区分大小写
bool isAlphabet(char ch)
{
  return ((ch >= 65 && ch <= 90)||(ch >= 97 && ch <= 122)); 
}
//从两头到中间找,然后替换
char* reverseStringByOrder(char * str)
{
int length=strlen(str);//字符串长度
int left=0,right=length-1;
while(left<right)
{
//跳过非字母
while(!isAlphabet(str[left]))
{
left++;
}
//跳过非字母
while(!isAlphabet(str[right]))
{
right--;
}
///////////交换两个字母
char temp=str[left];
str[left]=str[right];
str[right]=temp;
left++;
right--;
}
return str;
}
int main(int argc, char* argv[])
{
char test []="1w4rt,5t7?9u";
printf("the result:%s\n",reverseStringByOrder(test));
return 0;
}

#21


00

#22


//C/C++ 用交換法。
inline bool isalpha(char a){return (a>='a' && a<='z')||(a>='A' && a<='Z');}
inline void swap(char *a,char *b){char c = *b ; *b = *a ;  *a = c ; }
void ReverseAlpha(char *source)
{
  if(source == NULL)
    return ; 
  char *pb = source;
  char *pe = pb;
  while(*pe)++pe ;
  for(; *pb ; ++pb)
  {
    if(isalpha(*pb))
    {
      while(!isalpha(*pe)) --pe ;
      if(pb < pe)  //已交換完成
        swap(pb,pe--);
      else
        break;
    }
  }
}
int main(int argc, char* argv[])
{
    char *test = "1w4rt,5t7?9u";
    ReverseAlpha(test);  //1u4tt,5r7?9w
    printf("the result:%s\n",test);
    return 0;
}

#23


该回复于2014-10-04 09:52:25被版主删除

#24


顶一个

#25


顶,MARK

#26


字符数组

#27


用两个变量标记第一个和最后一个字母,交换完向中间推进,一直到碰头就完了嘛 

#28


用c++还可以,不过要思考一下。c#就不懂了

#29


堆栈法:
#include "stdio.h"

char Stack[20] = {0};
char *psBottom = Stack;
char *psTop = Stack;

char Input[20] = "1w4rt,5t7?9u";

void main()
{
char *pIndex = Input;

while (*pIndex != '\0')
{
if ((*pIndex >= 'a')&&(*pIndex <= 'z'))
{
*psTop = *pIndex;
psTop++;
}

pIndex++;

if (psTop > (psBottom + 20))
{
break;
}
}

pIndex = Input;

while (*pIndex != '\0')
{
if ((*pIndex >= 'a')&&(*pIndex <= 'z'))
{
if (psTop > psBottom)
{
psTop--;
*pIndex = *psTop;
}
}

pIndex++;
}

printf("%s\n",Input);
}

#30


20楼的程序特别的不错!支持!

#31


同意楼上的,风格很好,值得学习。
呵呵

#32


不错

#33


 急求:本人欲在傲游(Maxthon)浏览器的工具栏上安装一个自定义按钮,该按钮的功能是:当我按下该按钮时,启动d:\euro\hot.exe程序(该程序功能是:在当前网页中,搜索关键字,并将搜索结果及相关字段内容存入名为Asia2008.dbf数据库中,关闭当前网页)。请各位大侠指点做法,如有可能给出相关源程序,小生万分感谢!(Euro2000@126.com)

#34


我想 初始化一个数组都为零 长度等于字符串 遍历数组 把是字母的地方改为1,然后按着数组,把是1的地方的字目交换顺序

#35


ding

#36


很强大啊!

#37


up

#38


niu ,不错啊

#39


来学习一下了  

#40


                                 c
#include<stdio.h>
#include<string.h>
#define ISLETTER(t,i) ((t[i]>='a'&&t[i]<='z') || (t[i]>='A'&&t[i]<='Z'))
int main()
{
    char test[]="hello,the world !><abc;sample)((hit)(kill)(s))@#foolish#want r!+=";
    int i,j;
    char mid;
    printf("排序测试!\n");
    printf("原始数组: %s\n\n",test); 
    j=strlen(test)-1;
    printf("数组长度: %d\n",j+1); 
    for(i=0;i<=j;i++)
    {
       if( !ISLETTER(test,i) )
            continue;
        while( !ISLETTER(test,j) )
            j--;
        mid=test[i];
        test[i]=test[j];
        test[j]=mid;
        printf("%d 与 %d 互换\n",
        j--;
     }
     printf("排序后:   %s\n",test); 
     getch();
     return 0;
}

        
            
     

#41


很强啊,收藏了!

#42


第一感觉这就是个体力活!
用指针慢慢点吧

#43


回帖是一种美德!传说每天回帖即可获得 10 分可用分回帖是一种美德!传说每天回帖即可获得 10 分可用分

#44


收藏了,学习了一种好思路

#45


一个头指针,一个尾指针。

#46


20楼的方法比较好
应该前后同时找,左边找到的第n个和右边找到的第n个互换位置。这样就可以了。

#47


#include<stdio.h>

bool ischar(char pstr) //判读一个字符是否为字母,不区分大小写
{
if((pstr>=65)&&
(pstr<=90)||
(pstr>=97)&&
(pstr<=122))
return 1;
else
return 0;
}
char *reverse(char *str)//从两头到中间找,然后替换
{
char *left,*right,*tmp;

left=str;
        tmp=str;

        while(*tmp!='\0')
         tmp++;
        right=tmp-1;

while(left<right)
{
while(!ischar(*left))//跳过非字母
{left++;}

while(!ischar(*right))// 跳过非字母
{right++;}

char tmp=*left;/////////////交换两个字母
//str[left]=str[right];
*left=*right;
*right=*left;
*right=tmp;
left++;
right--;
}
return str;
}
void main()
{
char ch[]="a11b";
reverse(ch);
printf("%s\n",ch);
}

#48


手头没有工具
说下我的思路吧!
提取里面的每个字符保存起来,然后转换成int型 要加try、catch 用if判断不报错就保存 然后置换 ok

#49



void Reverse(char *p)
{
char  temp;
char *first = p;
char *end = p + strlen(p) - 1;
while(first < end)
{
while(!isalpha(*first))++first;
while(!isalpha(*end))--end;
temp = *first;
*first = *end;
*end = temp;
++first;
--end;
}
}

#50


学到了东西!