我们有一个语言X,它有一个字节和两个字节的字符。这种语言具有以下特征。
问题是,我们被赋予一个任意长度的字符串和指向字符串中某个字节的指针,我们必须找出前一个字符是什么以及下一个字符是什么。
一个简单的方法是从字符串的开头开始,检查字节的值并比较指针直到我们到达给定的指针。但在最坏的情况下,如果给定指针指向给定字符串中的最后一个字节,我们必须循环遍历所有字符。
我想知道是否有更好的算法可以在不考虑字符串长度的情况下以恒定时间给出结果?
答案 0 :(得分:12)
不,恒定时间是不可能的,因为最糟糕的情况是,正如Olexiy所说,几乎整个字符串都是最高位设置的字节,你需要回溯到开始,找出哪个是第一个顶级位第一个双字节序列中的-set字节。
希望这种病态很罕见,您可以一次退回一个字节,直到遇到任何低字节为止,在这种情况下,您可以确定之后的字节是它的开头一个人物。然后,您可以再次向前走,直到遇到原始指针。
答案 1 :(得分:7)
在最坏的情况下,我们需要经历整个字符串。只考虑字符A = 100和B = 200,C = 201以及以下长度为N的字符串:
S1 = ABCBCBC ...... BC
S2 = BBCBCBC ... BC
答案 2 :(得分:1)
向后扫描,直到您点击两个小于127的连续字节或者您点击字符串的开头。现在,您可以将字符计算到当前字符之后的字符数。
答案 3 :(得分:1)
让我们看看......你已经指向一个可以是单字节或双字节的字符。在后一种情况下,您可能位于此角色的第一个或第二个字节。所以首先你需要知道你是否处于一个角色的开头。 更糟糕的是,两个字节字符的第二个字节可以是任何值,因此所有字节都有可能大于127!这使得找到前一个角色变得很糟糕。但首先,确定你是在一个新角色的开头还是在一个角色的中间。
确定字符开始:返回一个字节,直到找到一个没有设置最高位的字节。 (或字符串的开头。)根据设置最高位的字节数,您将知道您是否处于开头。在当前字节之前设置的奇数个高位意味着您必须向后移动当前字符的一个字节。
确定上一个字符:返回两个字节。如果设置了最高位,则找到它。如果没有,请前往一个字节。
确定下一个字符:检查当前字节的最高位。如果设置,则向前转两个字节。否则,只有一个。
确定字符数意味着您转到字符串的开头并检查每个字节的最高位。如果设置,请在计数中添加一个并跳过一个字节。如果没有设置,只需在计数中添加一个。不幸的是,你必须经历整个字符串。
我确实假设您有某种方式来指示字符串的开头和结尾。如果没有,则没有迹象表明它的起点和终点。 (除非你使用空字节来表示启动/停止,在这种情况下你不能跳过字节,因为你可能会跳过这样的空字节。)
有更快的方法吗?好吧,如果您知道开始/结束位置,那么您可以计算此字符串中的字节数。字符数将是此字符串中未设置其最高位的字节数。所以只有低于128的字节数!
答案 4 :(得分:0)
假设您知道如何在字符串中向后移动(并假设它们给出的指针实际上保证是当前字符的第一个字节,如果它是多字节的话)。只需向后移动两个字节。
如果当前-2> 127的数据则前一个字符是最后两个字节。如果当前-2的数据<127,则前一个字符为当前-1。
类似于下一个角色。如果当前+ 1的数据是<1。 127然后它是下一个字符,否则它是多个字符的开头。
如果你无法向后移动,那么在你到达当前位置之前,没有办法完成整个字符串的读取。使用堆栈来跟踪最后两个字节,当您点击当前地址时,前一个字符所需的所有数据都在堆栈中。
答案 5 :(得分:0)
<击>上: 备份2个字节。如果字节> 127,然后它是角色的开头,否则前一个角色从下一个角色开始。
<击>下一步: 如果当前字节是> 127,然后下一个字符以2个字节开始,否则下一个字符以1个字节开始。
答案 6 :(得分:0)
你真的需要找到三个字符:当前字符,前一个字符和下一个字符。
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得到NextChar。如果P大于127,则下一个字符位于P + 2。如果P小于127,则NextChar位于P + 1位置。
答案 7 :(得分:0)
假设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;
}