【问题标题】:Interview Question: Finding Next and Previous characters in a given string?面试问题:在给定的字符串中查找下一个和上一个字符?
【发布时间】:2009-08-31 14:26:07
【问题描述】:

我们有一种语言 X,它有一个字节和两个字节字符。该语言具有以下特点。

  1. 单字节字符值将始终小于或等于 127。
  2. 在双字节字符中,第一个字节总是大于 127,第二个字节值可以是任何值。

问题是,给定一个任意长度的字符串和指向字符串中某个字节的指针,我们必须找出前一个字符是什么,下一个字符是什么。

一种简单的方法是从字符串的开头开始,检查字节的值并比较指针,直到我们到达给定的指针。但在最坏的情况下,如果给定的指针指向给定字符串中的最后一个字节,我们必须遍历所有字符。

我想知道有没有更好的算法,无论字符串的长度如何,都能在恒定时间内给出结果?

【问题讨论】:

  • 小于 127?你不是说“小于等于 127”吗?
  • 替代标题:为什么 UTF-8 比 shift-jis 更好;)。

标签: algorithm


【解决方案1】:

不,恒定时间是不可能的,因为最坏的情况是,正如 Olexy 所说,几乎整个字符串都是最高位设置的字节,您需要从头回溯以找出哪个是第一个最高位- 设置前两个字节序列中的字节。

希望这种病态的情况很少见,您可以一次后退一个字节,直到遇到任何低字节,在这种情况下,您可以确定 之后的字节它是开始一个人物。然后,您可以再次向前走,直到遇到原来的指针。

【讨论】:

  • 回复:“然后你可以再次向前走,直到遇到原来的指针。”此时,您有一个奇数或偶数序列的最高位集字节。您不需要向前迈出一步——您需要找出长度的偶数或奇数,这将告诉您 &pos[-1] 还是 &pos[-2] 是前一个字符。我知道这一点是因为我上周有这个面试问题......
【解决方案2】:

似乎在最坏的情况下,我们需要遍历整个字符串。只需考虑字符 A = 100 和 B = 200、C = 201 以及以下长度为 N 的字符串:

S1 = ABCCBC...BC

S2 = BBCBCBC...BC

【讨论】:

  • 是的,但我想找到更好的算法。
  • 如您所见,在最坏的情况下没有更好的算法。如果您想要更好的平均水平,请参阅 bobince 的评论。
【解决方案3】:

向后扫描,直到找到小于 127 的两个连续字节,或者找到字符串的开头。您现在可以将字符数到您所在的位置,并在当前字符之后数到一个。

【讨论】:

    【解决方案4】:

    让我们看看...您已经指向一个可以是单字节或双字节的字符。在后一种情况下,您可能位于该字符的第一个或第二个字节上。所以首先你需要知道你是否处于角色的开头。 更糟糕的是,双字节字符的第二个字节可以是任何值,因此所有字节都有可能大于 127!这使得查找前一个字符变得令人讨厌。但首先,确定你是在一个新角色的开头还是在一个新角色的中间。

    • 确定字符开始:返回一个字节,直到找到没有设置最高位的字节。 (或字符串的开头。)根据设置了最高位的字节数,您将知道您是否在开头。在当前字节之前设置奇数个高位意味着您必须为当前字符后退一个字节。

    • 确定前一个字符:返回两个字节。如果设置了最高位,您就找到了。如果不是,则向前走一个字节。

    • 确定下一个字符:检查当前字节的最高位。如果设置,则向前走两个字节。否则,只有一个。

    • 确定字符数意味着您转到字符串的开头并检查每个字节的最高位。如果设置,则将计数加一并跳过一个字节。如果未设置,只需在您的计数中添加一个。不幸的是,您将不得不遍历整个字符串。

    我确实假设您有某种方式来指示字符串的开始和结束。如果不是,则没有迹象表明它从哪里开始和停止。 (除非您使用空字节来指示开始/停止,在这种情况下您不能跳过字节,因为您可能会跳过这样的空字节。)

    有没有更快的方法?好吧,如果您知道开始/结束位置,那么您可以计算此字符串中的字节数。字符数将是该字符串中最高位未设置的字节数。所以只计算小于128的字节数!

    【讨论】:

      【解决方案5】:

      假设您知道如何在字符串中向后移动(并假设他们给您的指针实际上保证是当前字符的第一个字节,如果它是多字节的话)。只需向后移动两个字节。

      如果当前 -2 处的数据 >127 则前一个字符是最后两个字节。如果当前 -2 处的数据

      下一个字符类似。如果当前 + 1 处的数据

      如果你不能向后移动,那么除了通读整个字符串直到你到达当前位置是没有办法的。使用堆栈来跟踪最后两个字节,当您点击当前地址时,前一个字符所需的所有数据都在堆栈中。

      【讨论】:

      • 当 current-2 是双字节序列的高字节和第二字节时失败。
      • 啊,真的。不会打扰编辑,因为您的解决方案看起来不错。
      【解决方案6】:

      你真的需要找到三个字符:当前字符、前一个字符和下一个字符。

      CurrentChar 位于指针给定的位置 P 或 P-1。如果位置 P 指向大于 127 的字节,则 P 是 CurrentChar。如果 P 小于 127,请查看 P-1。如果 P-1 大于 127,则 CurrentChar 为 P-1,否则 CurrentChar 位于位置 P。

      要获取 PreviousChar,请查看 CurrentChar - 2,如果大于 127 PreviousChar = CurrentChar -2 否则为 PreviousChar = CurrentChar -1

      下一个字符可以通过查看 P 来获得。如果 P 大于 127,则下一个字符在 P+2 处。如果 P 小于 127 NextChar 在位置 P+1。

      【讨论】:

      • 不正确,如果位置P指向大于127的字节,也可以是双字节字符的第二个字节
      【解决方案7】:

      上一页: 备份 2 个字节。如果字节> 127,那么它是字符的开始,否则前一个字符从下一个字符开始。

      下一步: 如果当前字节 > 127,则下一个字符从 2 个字节开始,否则下一个字符从 1 个字节开始。

      【讨论】:

      • -2 偏移处的字节可以>127,但不是字符的开头,而是双字节字符中的第二个字节。
      • 不正确。在前一种情况下,如果字节 > 127,它也可以是双字节字符的第二个字节。在下一个案例中相同
      【解决方案8】:

      假设 arr[] 就像一个字符串,指向一个字节的指针是指向 INDEX 的指针

      #include<stdio.h>
      #include<stdlib.h>
      int find_valid(int);
      int arr[]={128,12,128,19,128,127,128,12,32,145,12,223,54,76,23};
      int main(){
          int index=1;
          while(index != 0){
          printf("\nEnter the index:");
          scanf("%d",&index);
          if(arr[index] < 128){  // it can be the first byte or the second byte of the Two byte
                   if( arr[index -1] < 128 ) printf("\nThis is the first byte in itself"); 
                   else // index-1 >= 128
                      {
                         int count = find_valid(index-2);
                         if(count%2 == 0) printf("\n This is the second byte of the two bytes:");       
                         else printf("\nThis is the first byte in itself:");
                      }
                   }
          else{ // it can be the second or the first in the two bytes
                 if ( arr[index - 1] < 128 ) printf("\n This is the First byte of the two bytes:");
                 else{
                       int count = find_valid(index-2);
                       if(count%2 == 0) printf("\n This is the second byte of the two bytes:");
                       else printf("\nThis is the First byte of the two bytes:");
                      }
                }         
      
          printf("\nHave u seen the result:");
          scanf("%d",&index);}
      }
      
      int find_valid(int i){
          int count=0;
          while( (arr[i] > 127) && (i>0) ) { ++count; --i;}
              return count;    
      }   
      

      【讨论】:

      • 要正确格式化代码,选择它并按“101010”按钮。
      猜你喜欢
      • 1970-01-01
      • 2011-09-26
      • 2018-11-20
      • 1970-01-01
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多