算法(一)

以下算法參考 <<算法>> 第4版[美] Robert Sedgewick

1. 歐幾里德算法
- (void)viewDidLoad {
    [super viewDidLoad];
    [self calculateGreatestCommonDivisorP:30 q:6]; //歐幾里德算法:求兩個(gè)數(shù)的最大公約數(shù)
}
#pragma mark - 歐幾里德算法
/**
 計(jì)算兩個(gè)非負(fù)整數(shù) p 和 q 的最大公約數(shù):若 q 是 0,則最大公約數(shù)為 p嘿期。否則赡若,將 p 除以 q得到余數(shù)r仓蛆,p和q的最大公約數(shù)即為q和 r 的最大公約數(shù)睬涧。
 greatest common divisor: 最大公因子
 */
- (int)calculateGreatestCommonDivisorP:(int)p q:(int)q {
    NSLog(@"p 和 q 的最大公約數(shù)============ %d", gcd(p, q));
    return gcd(p,q);
}

int gcd (int p, int q) {
    if (q == 0) {
        return p;
    }
    int r = p % q;
    return gcd(q, r);
}

2. 找出數(shù)組中最大的元素
- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *array = @[@2.6, @3, @9.6, @8, @5, @6];
    [self getMaxNumInArray:array];    //找出數(shù)組中組大的元素
}
- (NSNumber *)getMaxNumInArray:(NSArray *)array
 {
    double max = [array[0] doubleValue];
    for (int i = 1; i < array.count; i ++) {
        if ([array[i] doubleValue] > max) {
            max = [array[i] doubleValue];
        }
    }
    NSLog(@"MaxNumInArray===========%@", @(max));
    return @(max);
}
注:這里不能直接用 NSNumber, 直接用 NSNumber 浮點(diǎn)數(shù)會(huì)出錯(cuò).
3. 計(jì)算數(shù)組元素的平均值
- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *array = @[@2.6, @3, @9.6, @8, @5, @6];
    [self calculateAverageInArray:array];    // 計(jì)算數(shù)組元素的平均值
}
- (NSNumber *)calculateAverageInArray:(NSArray *)array {
    NSInteger length = array.count;
    double sum = 0.0;
    double average = 0.0;
    for (NSInteger i = 0; i < length; i ++) {
        sum += [array[i] doubleValue];
        average = sum / length;
    }
    NSLog(@"calculateAverage===========%@", @(average));
    return @(average);
}
4. 復(fù)制數(shù)組
注:示例數(shù)組中是NSNumber類型元素,其它類型需要另寫(xiě)方法
- (void)viewDidLoad {
    [super viewDidLoad];
    [self copyArray:array];     // 復(fù)制數(shù)組:示例數(shù)組中是數(shù)字
}
- (NSArray *)copyArray:(NSArray *)array {
    NSInteger length = array.count;
    NSMutableArray * copyArrayM = [NSMutableArray array];
    for (NSInteger i = 0; i < length; i ++) {
        copyArrayM[i] = array[i];
    }
    NSArray *copyArray = copyArrayM;
    return copyArray;
}
5. 顛倒數(shù)組元素的順序
- (void)viewDidLoad {
    [super viewDidLoad];
    [self reverseArray:array];  // 顛倒數(shù)組元素的順序
}
- (NSArray *)reverseArray:(NSArray *)array {
    NSInteger N = array.count;
    NSMutableArray *arrayM = [NSMutableArray array];
    for (NSInteger i = 0; i < N; i ++) {
        [arrayM addObject:array[i]];
    }
    for (NSInteger i = 0; i < N/2; i++) {
        NSNumber *temp = arrayM[i];
        arrayM[i] = arrayM[N-1-i];
        arrayM[N-i-1] = temp;
    }
    array = arrayM;
    return array;
}

-----------典型靜態(tài)方法的實(shí)現(xiàn)-------------

6. 計(jì)算一個(gè)數(shù)的絕對(duì)值:浮點(diǎn)數(shù)和整數(shù)
- (void)viewDidLoad {
    [super viewDidLoad];
    NSNumber *numAbs = [self calculateNumAbs:-234];
    NSLog(@"calculateDoubleAbs========%@", numAbs);
}
- (NSNumber *)calculateNumAbs:(double)x {
    if (x<0.0) {
        return @(-x);
    }
    else {
        return @(x);
    }
}
7. 判定一個(gè)數(shù)是否是素?cái)?shù):prime number
- (void)viewDidLoad {
    [super viewDidLoad];
    BOOL isPrime = [self isPrime:17];   // 判定一個(gè)數(shù)是否是素?cái)?shù)
    NSLog(@"isPrime===========%d", isPrime);
}
- (BOOL)isPrime:(NSInteger)N {
    if (N < 2) {
        return false;
    }
    for (NSInteger i = 2; i*i <= N; i++) {
        if (N % i == 0) {
            return false;
        }
    }
    return true;
}
8. 計(jì)算平方根(牛頓迭代法)
- (void)viewDidLoad {
    [super viewDidLoad];
    double numSqrt = [self calculateSqrt:-1];
    NSLog(@"numSqrt=========%f", numSqrt);
}
- (double)calculateSqrt:(double)c {
    if (c < 0) {
        return NAN;
    }
    double err = 1e-15;
    double t = c;
    while (fabs(t - c/t) > err * t) {
        t = (c/t + t) / 2.0;
    }
    return t;
}
9. 計(jì)算直角三角形的斜邊
- (void)viewDidLoad {
    [super viewDidLoad];
    double hypotenuse = [self calculateHypotenuse:5 :12];
    NSLog(@"hypotenuse=========%f", hypotenuse);
}
- (double)calculateHypotenuse:(double)a :(double)b {
    return sqrt(a*a + b*b);
}
10. 計(jì)算調(diào)和級(jí)數(shù)
- (void)viewDidLoad {
    [super viewDidLoad];
    double HarmonicSeries = [self calculateHarmonicSeries:5];
    NSLog(@"HarmonicSeries=========%f", HarmonicSeries);
}
- (double)calculateHarmonicSeries:(NSInteger)N {
    double sum = 0.0;
    for (int i = 1; i <= N; i++) {
        sum += 1.0 / i;
    }
    return sum;
}
11. 二分查找的遞歸實(shí)現(xiàn)
注: 二分查找的遞歸實(shí)現(xiàn): 數(shù)組內(nèi)數(shù)字大小是有序的(從大到小)
- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *intArray = @[@2, @3, @4, @10, @19, @20];
    NSInteger rankNum = [self rank:20 :intArray];
    NSLog(@"rankNum=========%ld", (long)rankNum);
}
- (NSInteger)rank:(NSInteger)key :(NSArray<NSNumber *> *)array {
    return [self rank:key :array :0 :array.count - 1];
}
- (NSInteger)rank:(NSInteger)key :(NSArray *)array :(NSInteger)low :(NSInteger)high {
    //如果key存在于a[]中舱权,它的索引不會(huì)小于low且不會(huì)大于high
    if (low > high) {
        return -1;
    }
    NSInteger mid = low + (high - low) / 2;
    if (key < [array[mid] integerValue]) {  //若小于array[mid],則往前查找
        return [self rank:key :array :low :mid-1];
    }
    else if (key > [array[mid] integerValue]) { //若大于array[mid],則往后查找
        return [self rank:key :array :mid+1 :high];
    }
    else {
        return mid;
    }
}

關(guān)于遞歸:編寫(xiě)遞歸代碼時(shí)最重要的有以下三點(diǎn)
1. 遞歸總有一個(gè)最簡(jiǎn)單的情況——方法的第一條語(yǔ)句總是一個(gè)包含 return 的條件語(yǔ)句矗晃。
2. 遞歸調(diào)用總是去嘗試解決一個(gè)規(guī)模更小的子問(wèn)題,這樣遞歸才能收斂到最簡(jiǎn)單的情況宴倍。上面的代碼中张症,第四個(gè)參數(shù)和第三個(gè)參數(shù)的差值一直在縮小仓技。
3. 遞歸調(diào)用的父問(wèn)題和嘗試解決的子問(wèn)題之間不應(yīng)該有交集。上面的代碼中俗他,兩個(gè)子問(wèn)題各自操作的數(shù)組部分是不同的脖捻。

-----------隨機(jī)數(shù)---------

12. 隨機(jī)返回 [a,b) 之間的一個(gè) double 值
- (void)viewDidLoad {
    [super viewDidLoad];
    double doubleRandom = [self uniform:1 :3];
    NSLog(@"doubleRandom=========%f", doubleRandom);
}
- (double)uniform:(double)a :(double)b {
    #define ARC4RANDOM_MAX      1000000
    return a + ((double)(arc4random()%ARC4RANDOM_MAX)/ARC4RANDOM_MAX) * (b-a);
}
13. 隨機(jī)返回 [0,N-1] 之間的整數(shù),值域:[0,N-1]
- (void)viewDidLoad {
    [super viewDidLoad];
    NSInteger intRandomZeroToHigh = [self arc4randomHigh:5];
    NSLog(@"intRandomZeroToHigh=========%ld", (long)intRandomZeroToHigh);
}
- (NSInteger)arc4randomHigh:(NSInteger)high {
    return arc4random() % high;
}
14. 隨機(jī)返回 [low,high-1] 之間的整數(shù),值域:[low,high]
- (void)viewDidLoad {
    [super viewDidLoad];
    NSInteger intRandomLowToHigh = [self arc4randomLow:3 high:5];
    NSLog(@"intRandomLowToHigh=========%ld", (long)intRandomLowToHigh);
}
- (NSInteger)arc4randomLow:(NSInteger)low high:(NSInteger)high {
    return low + arc4random() % (high-low);
}
15. 根據(jù)離散概率隨機(jī)返回的 int 值(出現(xiàn) i 的概率為 a[i])
- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *discreteArray = @[@0.2,@0.09,@0.3,@0.11,@0.3]; // a[]中各元素之和必須等于1
    NSInteger discrete = [self discrete:discreteArray];
    NSLog(@"discrete=======%zd", discrete);
}
- (NSInteger)discrete:(NSArray *)array {
    // a[]中各元素之和必須等于1
    #define ARC4RANDOM_MAX      1000000
    double r = (double)(arc4random()%ARC4RANDOM_MAX)/ARC4RANDOM_MAX;    // [0,1)隨機(jī)數(shù)
    double sum = 0.0;
    for (NSInteger i = 0; i < array.count; i++) {
        sum = sum + [array[i] doubleValue];
        if (sum >= r) {
            return i;
        }
    }
    return -1;
}
16. 隨機(jī)將 double 數(shù)組中的元素排序
- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *beforeShuffleArray = @[@2,@10.09,@2.3,@0.11,@6.3];
    NSArray *afterShuffleArray = [self shuffle:beforeShuffleArray];
    NSLog(@"afterShuffleArray = %@", afterShuffleArray);
}
/// 隨機(jī)將 double 數(shù)組中的元素排序
- (NSMutableArray *)shuffle:(NSArray *)array {
    NSMutableArray *arrayM = [NSMutableArray array];
    for (NSNumber *num in array) {
        [arrayM addObject:num];
    }
    NSInteger N = arrayM.count;
    for (NSInteger i = 0; i < N; i++) {
        // 將a[i]和a[i..N-1]中任意一個(gè)元素交換
        NSInteger r = i + arc4random() % (N-i);
        double temp = [arrayM[i] doubleValue];
        arrayM[i] = arrayM[r];
        arrayM[r] = @(temp);
    }
    return arrayM;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市兆衅,隨后出現(xiàn)的幾起案子地沮,更是在濱河造成了極大的恐慌,老刑警劉巖涯保,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诉濒,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡夕春,警方通過(guò)查閱死者的電腦和手機(jī)未荒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)及志,“玉大人片排,你說(shuō)我怎么就攤上這事∷俪蓿” “怎么了率寡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)倚搬。 經(jīng)常有香客問(wèn)我冶共,道長(zhǎng),這世上最難降的妖魔是什么每界? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任捅僵,我火速辦了婚禮,結(jié)果婚禮上眨层,老公的妹妹穿的比我還像新娘蹭秋。我一直安慰自己贝咙,他們只是感情好扎酷,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布尚卫。 她就那樣靜靜地躺著,像睡著了一般叁征。 火紅的嫁衣襯著肌膚如雪纳账。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天航揉,我揣著相機(jī)與錄音塞祈,去河邊找鬼。 笑死帅涂,一個(gè)胖子當(dāng)著我的面吹牛议薪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播媳友,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼斯议,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了醇锚?” 一聲冷哼從身側(cè)響起哼御,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎焊唬,沒(méi)想到半個(gè)月后恋昼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赶促,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年液肌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸥滨。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嗦哆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出婿滓,到底是詐尸還是另有隱情老速,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布凸主,位于F島的核電站橘券,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏卿吐。R本人自食惡果不足惜旁舰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望但两。 院中可真熱鬧鬓梅,春花似錦、人聲如沸谨湘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)紧阔。三九已至坊罢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間擅耽,已是汗流浹背活孩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乖仇,地道東北人憾儒。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓询兴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親起趾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诗舰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容