Swift 语言初探1

1.赌博游戏

游戏规则:
  扔2颗色子,如果第一次扔出的点数之和为7或11,玩家赢。如果第一次扔出的点数之和为2,3或11,庄家赢。如果摇出其他点数,那么游戏继续。之后的游戏中,如果点数之和为7,庄家赢。如果点数之和为第一次玩家摇出的数字,玩家赢。直到一方获胜,游戏结束。


逻辑分析:
  游戏第一次赢的规则和后面赢的规则不一样。所以需要分两种情况进行讨论。如果第一次点数为7或11,玩家赢。如果第一次点数为2,3或11,庄家赢。要是没有分出胜负,游戏将继续。由于玩家第二次以后赢的条件是摇出第一次摇出的点数。所以,在程序中,我们需要一个常量来保存第一次摇出的点数。同时,由于庄家赢的条件是摇出的点数为7。所以,我们需要一个变量来保存当前摇出的点数。同时,在循环中,我们需要控制程序在有一方获胜的时候终止循环。所以,我们需要给循环执行的条件。一方获胜的时候,改变其值,让循环终止。


完整代码

var money = 1000
var bet = 0
while money > 0 {
    print("玩家总资产:¥\(money)元")
    // 判断下注是否正确,如果下注错误,则循环
    repeat {
        print("请下注:",terminator:"")
        bet = inputInt()
    }while bet < 0 || bet > money

    func roll() -> Int {
        return Int(arc4random_uniform(6)) + 1
    }
    var isWin = false
    var i = 1
    let firstNum = roll() + roll()

    print("第\(i)次摇出了\(firstNum)")
    if firstNum == 7 || firstNum == 11 {
        print("玩家赢")
        money += bet
    }
    else if firstNum == 2 || firstNum == 3 || firstNum == 12 {
        print("庄家赢")
        money -= bet
    }
    else {
        isWin = true
    }

    while isWin {
        i += 1
        let num = roll() + roll()
        print("第\(i)次摇出了\(num)")
        if num == 7 {
            print("庄家赢")
            isWin = false
            money -= bet
        }
        else if num == firstNum {
            print("玩家赢")
            money += bet
            isWin = false
        }
    }
}
if money == 0 {
    print("你破产了!")
}

2.五人分鱼

问题简述:
  5个渔夫在一天打了很多鱼。第二天早上,第一个渔夫醒来,将鱼分成了5份,发现多了1条,将这条鱼扔了,然后拿走了属于自己的一份。第二个渔夫醒来,将剩下的鱼又平均分成了5份,又发现多了一条,于是将这条鱼扔了之后,拿走了属于自己的1份。之后渔夫依次做了同样的事。问这一伙渔夫至少打了多少条鱼?


逻辑分析:
  假设我们有足够多的鱼给5人分,鱼的数量需要满足的条件就是能够5次循环执行扔一条后能被5整除。由于每次剩下的鱼的数量都是原来的数量减去一条之后的5分之4。所以我们需要一个变量来保存此时鱼的数量,鱼的总数就等于此时鱼的数量。直到某一刻鱼的数量满足5次执行循环。那么将鱼的数量赋值给总数。其中,我们要让鱼的数量做5次循环,如果此时鱼的数量不足以执行5次循环,那么我们要终止本次循环。让鱼的数量增加,再重复循环。所以,这里我们需要一个Bool值,如果鱼的数量布满足循环条件。那么将Bool赋值为false。如果,最后Bool值没有被赋值为false,那么此时鱼的数量即为5个渔夫最少打的鱼数量。


完整代码

var total = 1  //鱼的总数
while true {
    var fish = total    //当前鱼的数量
    // 模拟5人分鱼
    var isFind = true
    for _ in 1...5 {
        //if条件必须执行5次
        if (fish - 1) % 5 == 0 {
            fish = (fish - 1) / 5 * 4
        }
        //如果当前鱼的数量不满足执行5次的条件,则终止循环
        else {
            isFind = false
            break
        }
    }
    if isFind {
        print(total)
        break
    }
    //将鱼的总数加1
    total += 1
}

3.百钱百鸡

问题简述
  我们需要用100块钱买100只鸡。其中,公鸡5块钱一只,母鸡3块钱一只,小鸡1块钱3只。问有哪些买法,满足条件?


逻辑分析
  首选需要确定3个变量来保存公鸡,母鸡,小鸡的数量。然后3个变量需要满足的条件:相加等于100,价格相加等于100。


完整代码

//公鸡数量的循环范围
for x in 0..<20 {
    //母鸡数量的循环范围
    for y in 0..<33 {
        for z in  0...99 {
        // 如果满足公鸡+母鸡+小鸡的数量为100,小鸡的数量是3的倍数,打印
            if 5 * x + 3 * y + z / 3 == 100 && z % 3 == 0 && x + y + z == 100 {
                print("公鸡\(x)只,母鸡\(y)只,小鸡\(z)只")
            }
        }
    }
}

1.整个循环条件就是围绕价格相加为100,数量相加为100,同时小鸡的数量是3的倍数。开始我错误的将z = 100 - x - y作为了z的循环范围。后面发现打印的结果非常多。提醒了我需要清楚条件和循环范围的区别。

2.关于最后一个z循环,其实可以不需要。因为公鸡的数量确定了,母鸡的数量确定了,那么小鸡的数量就确定了。优化后的代码如下

//公鸡数量的循环范围
for x in 0..<20 {
    //母鸡数量的循环范围
    for y in 0..<33 {
        let z = 100 - x - y
        // 如果满足公鸡+母鸡+小鸡的数量为100,小鸡的数量是3的倍数,打印
            if 5 * x + 3 * y + z / 3 == 100 && z % 3 == 0  {
                print("公鸡\(x)只,母鸡\(y)只,小鸡\(z)只")
            }
    }
}

因为少了一层内循环。所以程序的时间复杂度大大的降低。提高了程序的响应时间。这个优化在真实项目中的使用非常重要。


4.数组中两种排序算法

简单选择排序原理:
  假设数组第一个数是最小的数,记录其下标。比较后面每一个元素。如果后面的其中一个元素小于当前最小数,那么记录其下标,并将其元素作为最小数,直到数组最后一个数比较完。将最小数通过记录的下标交换到第一个位置。依次类推第二个位置,第三个位置的元素。
完整代码

var array = [23,6,88,14,58,33,56,93,19]
for j in 0..

冒泡排序原理:
  数组中相邻2个元素比较,如果后面一个元素小于前面一个元素,那么交换其元素。最后一个元素即为最大元素。依次类推倒数第二个元素,倒数第三个元素。

var array = [23,6,88,14,58,33,56,93,19]
for j in 0.. array[i + 1] {
            (array[i + 1],array[i]) = (array[i],array[i + 1])
            isEnough = true
        }
    }
    //如果循环没有执行,那么直接终止循环
    if !isEnough {
        break
    }
}
print(array)

我的体会
1.对于选择排序中,我认为很重要的就是定义一个变量来保存最小元素的下标。如果当前元素小于保存的最小元素,那么就交换其值。
2.对于冒泡排序,这种排序。我认为对于定义Bool值来检查交换是否执行是一个很重要的优化。当序列即将有序的时候,效率将大大增强。

你可能感兴趣的:(Swift 语言初探1)