代码改变世界

算法——字符串(22%)

2012-12-18 15:11  msfte  阅读(635)  评论(0编辑  收藏  举报

 1,颠倒一个字符串。

2,颠倒一个句子中的词的顺序,比如将"我叫克丽丝"转换为"克丽丝叫我",

3, 找到一个子字符串。

4,比较两个字符串,用O(n)时间和恒量空间。

5, 翻转句子中单词的顺序。 

题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。 

句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。 

例如输入"

I am a student.",则输出"student. a am I"。

6, 在一个字符串中找到第一个只出现一次的字符。如输入

abaccdeff,则输出b

7, 输入一个表示整数的字符串,把该字符串转换成整数并输出。

8, 写一个函数

,它的原形是int continumax(char *outputstr,char *intputstr)

功能:

在字符串中找出连续最长的数字串,并把这个串的长度返回,

并把这个最长数字串付给其中一个函数参数

outputstr所指内存。

例如:

"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回9

17 

outputstr

所指的值为

123456789

9, 左旋转字符串(字符串)

题目:

定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。

如把字符串

abcdef左旋转2位得到字符串cdefab。请实现字符串左旋转的函数。

要求时间对长度为

n的字符串操作的复杂度为O(n),辅助内存为O(1)

10, 实现一个挺高级的字符匹配算法: 

给一串很长字符串,要求找到符合要求的字符串,例如目的串:

123

1******3***2 ,12*****3 

这些都要找出来

11,n个长为m+1的字符串,

如果某个字符串的最后

m个字符与某个字符串的前m个字符匹配,则两个字符串可以联接,

问这

n个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误。 

12, 输入一个字符串,打印出该字符串中字符的所有排列。 

例如输入字符串

abc,则输出由字符abc所能排列出来的所有字符串

abcacbbacbcacabcba 

分析:这是一道很好的考查对递归理解的编程题,

13, 如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,

则字符串一称之为字符串二的子串。

注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。

请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。

例如:输入两个字符串

BDCABAABCBDAB,字符串BCBABDAB都是是它们的最长公共子串,则输出它们的长度4,并打印任意一个子串。

分析:求最长公共子串(

Longest Common Subsequence, LCS)是一道非常经典的动态规划题,因此一些重视算法的公司像MicroStrategy都把它当作面试题。 

分析:动态规划:1,子结构:A[i,j],第一个串前i个字符和第二个串前j个字符。2,子结构状态:最长公共子串。3,状态转移:A[i,j] = max {A[i-1,j],A[j,i-1],A[i,j]+a[i]==b[j]?1:0};

代码:1,备忘录

        private int Memory(string array1, string array2)
        {
            return MemoryRecur(array1, array2, array1.Length - 1, array2.Length - 1);            
        }

        private int MemoryRecur(string array1, string array2, int first, int second)
        {
            if (first < 0 || second < 0)
                return 0;
            if (first == 0 && second == 0)
                if (array1[0] == array2[0])
                    return 1;
                else
                    return 0;
            int firstResult = MemoryRecur(array1, array2, first - 1, second);
            int secondResult = MemoryRecur(array1, array2, first, second - 1);
            int thirdResult = MemoryRecur(array1, array2, first - 1, second - 1);
            if (array1[first] == array2[second])
                thirdResult++;
            return GetMax(new int[] { firstResult, secondResult, thirdResult });
        }

        private int GetMax(int[] array)
        {
            if (array == null||array.Length == 0)
                throw new ArgumentException();
            if (array.Length == 1)
                return array[0];
            int max = array[0];
            for (int i = 1; i < array.Length; i++)
            {
                if (array[i] > max)
                    max = array[i];
            }
            return max;
        }

2,动态规划:

       private int GetMax(int[] array)
        {
            if (array == null||array.Length == 0)
                throw new ArgumentException();
            if (array.Length == 1)
                return array[0];
            int max = array[0];
            for (int i = 1; i < array.Length; i++)
            {
                if (array[i] > max)
                    max = array[i];
            }
            return max;
        }

        private int DynamicProgramming(string array1, string array2)
        {
            int[] cache = new int[array2.Length];
            int last = 0;
            for (int i = 0; i < array1.Length; i++)
            {
                for (int j = 0; j < array2.Length; j++)
                {
                    int iMinus = i > 0 ? cache[j] : 0;
                    int jMunis = j > 0 ? last : 0;
                    int ijMinus = i > 0 && j > 0 ? cache[j - 1] : 0;
                    if (array1[i] == array2[j])
                        ijMinus++;
                    if (j > 0) 
                        cache[j - 1] = last;
                    else
                        cache[array2.Length - 1] = last;
                    last = GetMax(new int[] { iMinus, jMunis, ijMinus });                    
                }
            }
            return cache[array2.Length - 1];
        }

 

 14, 在字符串中删除特定的字符(字符串)。

题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。

例如,输入"

They are students."和"aeiou",

则删除之后的第一个字符串变成"

Thy r stdnts."。

15,给出一个函数来输出一个字符串的所有排列(经典字符串问题)。

16,对称字符串的最大长度(字符串)。

题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。

比如输入字符串"

google",由于该字符串里最长的对称子字符串是"goog",因此输出4

17, 一个文件,内含一千万行字符串,每个字符串在1K以内,

要求找出所有相反的串对,如abccba

 

18, 给出一个函数来复制两个字符串AB 

 

字符串A的后几个字节和字符串B的前几个字节重叠。

19,已知一个字符串,比如asderwsde,寻找其中的一个子字符串比如sde的个数,

如果没有返回0,有的话返回子字符串的个数。

20, 求最大连续递增数字串(如"ads3sl456789DF3456ld345AA"中的"456789")

21,即在父串中寻找子串首次出现的位置。

 

22,函数将字符串中的字符'*'移到串的前部分,

前面的非'*'字符后移,但不能改变非'*'字符的先后顺序,函数返回串中字符'*'的数量。

如原始串为:ab**cd**e*12

处理后为*****abcde12,函数并返回值为5。(要求使用尽量少的时间和辅助空间)

23, 删除字符串中的数字并压缩字符串。

24, 求两个串中的第一个最长子串(神州数码以前试题)。 

"abractyeyt","dgdsaeactyey"的最大子串为"actyet"

25, 删除串中指定的字符 

26, 判断一字符串是不是对称的,如:abccba

 27,一个单词单词字母交换,可得另一个单词,如army->mary,成为兄弟单词。提供一个单词,在字典中找到它的兄弟。描述数据结构和查询过程。

 28,删除字符串开始及末尾的空白符,并且把数组中间的多个空格(如果有)符转化为1个。

29,字符串移动(字符串为*号和26个字母的任意组合,把*号都移动到最左侧,把字母移到最右侧并保持相对顺序不变),要求时间和空间复杂度最小 

30,假设两个字符串中所含有的字符和个数都相同我们就叫这两个字符串匹配,
 比如:abcda和adabc,由于出现的字符个数都是相同,只是顺序不同,
 所以这两个字符串是匹配的。

31,代码实现计算字符串的相似度

32,给定一个字符串里面只有"R" "G" "B" 三个字符,请排序,最终结果的顺序是R在前 G中 B在后。

33,实现atoi
34,字符串匹配 含有*

35,实现strcpy memmove

36,将一个很长的字符串,分割成一段一段的子字符串,子字符串都是回文字符串。
有回文字符串就输出最长的,没有回文就输出一个一个的字符。
例如:
habbafgh
输出h,abba,f,g,h。

37,输出一个字符串中没有重复的字符。如“baaca”输出“bac”。

38,分割字符串。
对于一个字符串,根据分隔符seperator,把字符串分割,如果存在多个分隔符连在一起,则当做一个分隔符。如果分隔符出现在" "符号之间,则不需要分割" "之间的字符。
比如a++abc ,分隔符为+,输出a abc
a+"hu+" 输出a hu+
a++"HU+JI 输出a "HU JI。
请根据上述需求完成函数:void spiltString(string aString,char aSeperator)。

 39,字符串数组S,全是0和1表示的,字符串都是n位的,且1的个数小于等于l,返回index的字符串。(这个比较奇怪,如果S中字符串都是符合1的个数小于等于l,则直接可以得到index的字符串啊,难道是要先求这个字符串数组?那就比较麻烦了

40,给定一个字符串,统计一下哪个字符出现次数最大。

41,用递归算法写一个函数,求字符串最长连续字符的长度,比如aaaabbcc的长度为4,aabb的长度为2,ab的长度为1

42,给定两个字符串s1和s2,要求判定s2是否能够被通过s1做循环移位(rotate)得到字符串包含。例如,S1=AABCD和s2=CDAA,返回true;给定s1=ABCD和s2=ACBD,返回false。用伪代码或流程图叙述解法。

43,找出字符串中的最长子串,要求子串不含重复字符

44,KMP

45,一个字符串,要求删去里面的括号包含的内容

非递归:

public void Run()
        {
            var normal = GetResult("fewfew(fdsfsa)fsdfwe");
            var onlyLeft = GetResult("fdsfas(fdsfsda");
            var onlyRight = GetResult("fdsfsda)afdsfsa");
            var doubleBracket = GetResult("fdsfas(fdsfdsf(gfdgsdf)gfdgfd)gfdgfds");
        }

        private string GetResult(string text)
        {
            int length = text.Length;
            var charArray = text.ToArray();
            Compute(charArray, ref length);
            char[] resultText = new char[length];
            for (int i = 0; i < length; i++)
                resultText[i] = charArray[i];
            return new string(resultText);
        }

        private void Compute(char[] text, ref int length)
        {
            //Validate
            if (text == null || text.Length == 0)
                throw new ArgumentException("text param is invalid.");
            if (length <= 0)
                throw new ArgumentException("length param is invalid");

            Stack<int> leftIndexs = new Stack<int>();

            for (int i = 0; i < length; i++)
            {
                if (text[i] == '(')                
                    leftIndexs.Push(i);                

                if (text[i] == ')')
                {
                    if (leftIndexs.Count == 0)
                        continue;
                    int left = leftIndexs.Pop();
                    int count = i - left + 1;
                    for (int j = i + 1; j < length; j++)
                        text[j - count] = text[j];
                    length -= count;
                    i -= count;
                }
            }
        }

 递归:

   

        static void StrCut(char[] str,int start,int end)
        {

            int i;
            for (i = 0; i < str.Length-end-1; i++)
            {
                str[start+i] = str[end+i+1];              
            }

            str[start + i] = '\0';
           
        }

        static void DeleteBraceRecur(char[] str, int start, int deep)
        {   
            int index =start+1;
            while (index < str.Length && str[index]!='\0')
            {
                if (str[index] == '(') {
                    DeleteBraceRecur(str, index,deep+1);                                  
                }
                else if (str[index] == ')' && deep>1) {

                    StrCut(str, start, index);
                    return;
                }
                index++;
 
            }   
        }

        static string DeleteBrace(string str) {

            char[] cStr = str.ToCharArray();
            DeleteBraceRecur(cStr, -1, 1);
            int count =0;

            while (count < str.Length && cStr[count] != '\0')
            {
                count++;
            }

            char[] result = new char[count];

            for (int i = 0; i < result.Length; i++) {

                result[i] = cStr[i];           
            }

            return new string(result);
        }
    

        static void Main(string[] args)
        {

            string str1=  "adasd((((()a(sdas)d(ads";
            string str2 = "a(((da)sd()a(sdas)d(wddwwdda)ds";
            string str3 = "adasd()a(sd(dwdwwdwdwd)as)d(ads";

            Console.WriteLine( DeleteBrace(str1));
            Console.WriteLine( DeleteBrace(str2));
            Console.WriteLine( DeleteBrace(str3));
        }

  

46,一个字符串,要求找出其中最长的单词。

        static string Max(string str1, string str2, string str3) {

            if (str1.Length > str2.Length)
            {

                if (str1.Length > str3.Length)
                {
                    return str1;
                }
                else
                {
                    return str3;
                }
            }
            else {

                if (str2.Length > str3.Length)
                {
                    return str2;
                }
                else
                {
                    return str3;
                }            
            }
        }


        static string GetLength(string str, int start, int end)
        {
            int mid = start + (end - start) / 2;

            int leftLength=0;
            int rightLength=0;

            if (str[mid] == ' ')
            {
                return "";
            }

            for (int i = mid-1; i >= start; i--)
            {
                if (str[i] == ' ')
                    break;
                leftLength++;
            }

            for (int i = mid+1; i <= end; i++)
            {
                if (str[i] == ' ')
                    break;
                rightLength++;
            }
           
            return str.Substring(mid - leftLength, rightLength + leftLength + 1);           
           
        }


        static string GetLongestWord(string str,int start,int end)
        {

            string midStr = GetLength(str,start,end);

            if (midStr.Length > (end - start) / 2)
            {
                return midStr;

            }

            int mid = start + (end - start) / 2;
            string leftSubStr = GetLongestWord(str,start,mid);
            string rightSubStr = GetLongestWord(str,mid,end);
            return Max(midStr,leftSubStr,rightSubStr);
           
        }

        static void Main(string[] args)
        {
           
            string str = "ds sdds sdfsdfdsfsfd ffd f f aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            string longestStr = GetLongestWord(str,0,str.Length-1);
        }