再說一道面試題及相應的測試[一個有序數組A[n],從中間某一點截斷, 把它前半部分接到后半部分的后面形成B[n], 請從B[n]找到A[n]截斷位置]

﻿﻿

１．　這個數組A必須是有序的, 有序就必須考慮兩種情況升序和降序.  假設所有都平序, 應該不滿足需要. 比如全為1

２．　這個找到截斷的位置，應該可以用二分法來做

３．　數組的個數應該必須大於等於２．　２個數的數組是可以的．　比如３，４．從４處截斷可以形成４，３

1． 　只有１個數的數組

２．　只有２個數的數組

３．　只有一個轉折的數組（升序）

４．　只有一個轉折的數組（降序）

５．　不止一個轉折的數組

６．　全升的數組

７．　全降的數組
８．　只有一個轉折的數組，轉折點左右重復數
９．　只有一個轉折的數組，非轉折點有重復數

public static int FindIndexFromArray(int[] bArray)
{
//Detect if A[n] is ASC or DSC order
bool isAscOrder = bArray[0] >= bArray[bArray.Length - 1];

//Use Binary Search
int low = 0;
int high = bArray.Length - 1;
int mid = -1;
while (true)
{
if ((low + high) / 2 != mid)
{
mid = (low + high) / 2;
if (isAscOrder && bArray[low] <= bArray[mid]
||
!isAscOrder && bArray[low] >= bArray[mid]
)
{
low = mid;
}

if (isAscOrder && bArray[mid] <= bArray[high]
||
!isAscOrder && bArray[mid] >= bArray[high]
)
{
high = mid;
}

if (low + 1 == high)
{
break;
}
}
else
{
throw new ArgumentException("The provided array did not match the rule. Please check!");
}
}

return bArray.Length - low - 2;
}

public static int[] ConstructArrayB(int[] aArray, int index)
{
if (aArray.Length < 2 || index > aArray.Length - 2)
{
throw new ArgumentException();
}

int[] bArrary = new int[aArray.Length];

for (int i = 0; i <= index; i++)
{
bArrary[i - index + aArray.Length - 1] = aArray[i];
}

for (int i = index + 1; i < aArray.Length; i++)
{
bArrary[i - index - 1] = aArray[i];
}

return bArrary;
}

public static void Print(int[] array)
{
foreach (int c in array)
{
Console.Write(c + " ");
}
Console.WriteLine();
}

static void Main(string[] args)
{
int[] a = { 1, 1, 2, 3, 3, 4,5,12,30 };
Console.WriteLine("數組A");
Print(a);
int index = 2;
Console.WriteLine("從{0}折斷數組A", index);
int[] b = ConstructArrayB(a, index);
Console.WriteLine("數組B:");
Print(b);
int index2 = FindIndexFromArray(b);
Console.Write("從數組B得到A的折斷點：{0}", index2);
Console.Write("判斷算法正確與否:{0}", index == index2 );
}

public static int FindIndexFromArray(int[] bArray)
{
//Detect if A[n] is ASC or DSC order
bool isAscOrder = bArray[0] >= bArray[bArray.Length - 1];

//Use Binary Search
int low = 0;
int high = bArray.Length - 1;
int mid = -1;
while (low <= high)
{
mid = (low + high) / 2;
if (isAscOrder && bArray[mid] > bArray[mid + 1]
||
!isAscOrder && bArray[mid] < bArray[mid + 1]
)
{
return bArray.Length - mid - 2;
}

if (isAscOrder && bArray[mid] <= bArray[high]
||
!isAscOrder && bArray[mid] <= bArray[high]
)
{
high = mid;
}
else
{
low = mid;
}
}

return bArray.Length - mid - 2;
}

﻿﻿
﻿﻿