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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值