找到长度未知的字符串或数组的中间部分。你可以 不遍历列表来查找长度。你可能不会使用任何东西 帮助你找到长度 - 因为它是“未知的”。 (即没有sizeof(C)或count(C#)等...)
我把这个问题作为面试问题。我只是想知道答案是什么。我确实问过我是否可以使用sizeof,他说“不,字符串或数组的大小是未知的 - 你只需要到达中间位置。”
顺便说一下,我不确定这是否真的可以在没有遍历的情况下解决。我几乎觉得他可能想看看我对自己的回答有多自信:S不确定......
他的英语很糟糕 - 也不确定这是否会导致误解。他直接告诉我,我不需要遍历列表就可以到达中间位置:S:S我假设他的意思是没有任何遍历.....:S
答案 0 :(得分:10)
有两个计数器,c1和c2。开始遍历列表,每次递增c1,每隔一次递增c2。当c1到达结束时,c2将在中间。
你没有“遍历列表来查找长度”,然后将其除以2,你刚刚经历了一次。
我能想到的唯一另一种方法是继续取下列表的第一个和最后一个项目,直到你留下中间的一个。
答案 1 :(得分:5)
您(或您的采访者)对数据的含义非常模糊(您提到“字符串”和“数组”);没有可以做出的假设,所以它可以是任何东西。
你提到字符串的长度是未知的,但是根据你的措辞,看起来你(或面试官)实际上意味着说不可知。
a)如果它只是未知,那么问题是,如何才能确定?例如,对于字符串,您可以将结尾视为'\0'
。然后,您可以应用一些算法,例如其他答案建议的算法。
最重要的是,你不能谈论一个没有开头和结尾的中间,或者一个长度。这个问题是故意无法回答的,或者你没有理解它。您必须知道的不仅仅是内存段的开头,也可能是它的类型。
答案 2 :(得分:1)
以下代码将找到没有遍历列表的数组的中间部分
int thearray[80];
int start = (int)&thearray;
int end = (int)(&thearray+1);
int half = ((end-start) / 4)/ 2;
std::cout << half << std::endl;
编辑:
此代码假设您正在处理实际数组而不是指向第一个元素的指针,因此代码如下:
int *pointer_to_first_element = (int *)malloc(someamount);
将不起作用,同样使用任何其他表示法将数组引用降级为指向第一个元素的指针。基本上任何使用*
的符号。
答案 3 :(得分:0)
您只需使用第一个和最后一个元素的地址之间的差异。
答案 4 :(得分:-1)
我认为这个问题的目的还在于测试您在问题分析和需求收集方面的技能。正如其他人之前所说,我们至少需要另一条数据来解决这个问题。
我的方法是让面试官清楚我们可以在函数调用中使用一个约束来解决问题:调用者必须提供2个指针,一个指向开头,另一个指向数组末尾。鉴于这两个指针,并使用基本指针算法,我达到了这个解决方案;请让我知道你对它的看法。
int *findMiddleArray( int const *first, int const *last )
{
if( first == NULL || last == NULL || first > last )
{
return NULL;
}
if( first == last )
{
return (int *)first;
}
size_t dataSize= ( size_t )( first + 1 ) - ( size_t )first,
addFirst= ( size_t )first,
addLast= ( size_t )last,
arrayLen= ( addLast - addFirst) / dataSize + 1,
arrayMiddle= arrayLen % 2 > 0 ? arrayLen / 2 + 1 : arrayLen / 2;
return ( int * )( ( arrayMiddle - 1 ) * dataSize + addFirst );
}
答案 5 :(得分:-1)
找到数组中点的一种方法是(对于奇数长度数组) 只需使用两个循环,第一个循环从 0 索引开始遍历,另一个(嵌套)循环将从数组的最后一个索引开始遍历。现在只需比较相同的元素......这将是数组的中点。即 if(arr[i]== arr[j]) 。希望你明白!
对于偶数长度数组..你可以做 if(arr[i] == arr[j-1]) 或者 if(arr[i] == arr[j+1]) 因为它们永远不会相同。试运行试一下!