20141008個人日誌(空數組添加元素不報錯,快速找出不成對出現的元素,隨機生成和爲S的N個正整數)

    項目中遇到這麼一個問題:一個單例對象,該單例有一個數組屬性,我要移除數組裏面的元素,移除之後還將此數組置空.之後再向此數組中加入元素,編譯器是不會報錯的.如下:

    NSMutableArray *array = [NSMutableArray alloc];

    array = nil;

    [array addObject:@"nil"];

很容易出錯的地方,需小心謹慎.

    今天編寫的小算法較多,都是來源於http://blog.csdn.net/column/details/algorithm-easyword.html.特此感謝!如下:

(1)

     題目:整數數組中除一個元素外,其他元素都是成對出現,要找出此唯一不成對出現的元素

  算法思路:用異或,兩個相同的整數取異或是0,所有元素取異或,結果就是落單的元素

/*參數說明:
    a           待查數組
  length        待查數組元素個數
 
 返回值說明:
   成功          則返回此不同的元素
   失敗          返回ERROR
 
 */
int FindTheSingleOneNum(int a[],int length)
{
    if (length < 1) {
        return ERROR;
    }
    
    if (length % 2 == 0) {
        return ERROR;
    }
    
    int targetValue = 0;
    for (int i=0; i<length; i++) {
        targetValue ^= a[i];
    }
    return targetValue;
}

(2)繼此題後還有另外一個類似的題目如下:

     題目:一個整數數組,裏邊元素只有兩個不是成對出現的,儘可能快的找出這兩個不同的數

  解題思想:受前面算法思想的影響,數組中只有一個不成對出現的元素時,全部異或即可求出此不成對出現的元素.於是可考慮將此數組分割成兩組數,使得這兩個不成對出現的數分別在不同的組中,再對此兩組數求異或即可求出這兩個不成對出現的數

/*!
<span style="font-family: Menlo;">參數說明:</span>
    a           待查數組
  length        待查數組元素個數
 
 返回值說明:
    成功         函數返回一個結構體,即兩個不成對出現的數
    失敗         返回相同的兩個數{-1,-1}
 */
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 16px; font-family: Menlo; color: rgb(187, 44, 162);">typedef<span style="color: #000000"> </span>struct<span style="color: #000000"> resultTwo</span></p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 16px; font-family: Menlo;">{</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 16px; font-family: Menlo;">    <span style="color: #bb2ca2">int</span> a;</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 16px; font-family: Menlo;">    <span style="color: #bb2ca2">int</span> b;</p><p style="margin-top: 0px; margin-bottom: 0px; font-size: 16px; font-family: Menlo;">}resultTwo;</p><div>
</div>
resultTwo FindTheSingleTwoNum(int a[],int length)
{
    if (length < 1) {
        return (resultTwo){ERROR,ERROR};
    }
    
    if (length % 2 == 1) {
        return (resultTwo){ERROR,ERROR};
    }
    
    int targetValue1 = 0;       // 存儲不是成對出現的數
    int targetValue2 = 0;
    int tempResult   = 0;       // 所有元素異或結果
    for (int i=0; i<length; i++) {
        tempResult ^= a[i];
    }
    
    if (tempResult == 0) {
        return (resultTwo){ERROR,ERROR}; // 若所有元素都是成對出現的(包括偶數對),則返回error
    }
    
    // 尋找兩個不成對出現的數的二進制位第一次出現不同數所在的位置
    int bitDif = -1;  // 兩個不成對出現的數,二進制從右往左第一次出現不同的數所在的位數(0開始)
    while (tempResult)
    {
        if ((tempResult & 1) == 0)
        {
            bitDif += 1;
            tempResult >>= 1;
        }
        else
        {
            bitDif += 1;
            break;
        }
    }
    
    // 根據以上的不同位數,將原數組分成兩組:此位相同的數在一組(分別0,1)
    for (int i=0; i<length; i++) {
        if (((a[i]>>bitDif) & 1) == 1)
        {
            targetValue1 ^= a[i];
        }
        else
        {
            targetValue2 ^= a[i];
        }
    }
    
    return (resultTwo){targetValue1,targetValue2};
}

(3)

     題目:隨機生成和爲SN個正整數

  

/*!
 思路:考慮每個數的取值範圍,然後在該範圍內隨機取值
 例如:隨機生成10個和爲100的正整數
    x1 + x2 +...+ x10 = 100
 每個 xi 至少爲1,所以不妨設: 1 =< x1 <= 100 - 9
 所以也不妨設: 1 =< x1 <= 100 - 8 - x1
 依次往下,直到最後一個元素,不能再隨機生成,利用和100減去前面所有的元素
 */

void GetRandomNumToFixSum(int a[],int eleNum,int sum)
{
    if (eleNum < 1) {
        return;
    }
    srand((unsigned)time(0));
    
    int sumFirst = 0;    //前 k 項和
    for (int i=0; i<eleNum - 1; i++)
    {
        a[i] = rand()%(sum - sumFirst - eleNum + i + 1) + 1;
        sumFirst += a[i];
    }
    a[eleNum-1] = sum - sumFirst;
}



發佈了33 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章