OVVO 发表于 2022-9-17 18:21

Python语法的25个练习题

本帖最后由 OVVO 于 2022-9-17 18:23 编辑

>最近在跟着B站的视频(aHR0cHM6Ly93d3cuYmlsaWJpbGkuY29tL3ZpZGVvL0JWMW5xNHkxazdCNA==)学习,完整看完了,记的所有笔记,这些题目也可灵活多变,你可以思考,如何去使用C、JAVA、GO等语言实现,记得留在评论区,一起学习,共同成长。

# 题目1:水仙花数

> 水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(Armstrong number),水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身。例如:1^3 + 5^3+ 3^3 = 153。

```python
for i in range(100, 1000):
    i1 = i // 100       # 取百位数字 123//100=1
    i2 = i // 10 % 10   # 取十位数字 123//10=1212%10=2
    i3 = i % 10         # 取个位数字 123%10=3

    if i1 ** 3 + i2 ** 3 + i3 ** 3 == i:
      print(f"{i}是水仙花数")
      # 153 是水仙花数
      # 370 是水仙花数
      # 371 是水仙花数
      # 407 是水仙花数
```

# 题目2:四叶玫瑰数

> 四叶玫瑰数是4位数的自幂数。自幂数是指一个 n 位数,它的每个位上的数字的 n 次幂之和等于它本身。(例如:当n为3时,有1^3 + 5^3 + 3^3 = 153,153即是n为3时的一个自幂数,3位数的自幂数被称为水仙花数)。

```python
for i in range(1000,10000):
    i1 = i // 1000      # 取千位数字 1234//1000=1
    i2 = i // 100 % 10# 取百位数字 1234//100=1212%10=2
    i3 = i // 10 % 10   # 取十位数字 1234//10=123123%10=3
    i4 = i % 10         # 取个位数字 1234%10=4
    # print(i,i1,i2,i3,i4)

    if i1 ** 4 + i2 ** 4 + i3 ** 4 + i4 ** 4 == i:
      print(f'{i}是四叶玫瑰数')
      # 1634 是四叶玫瑰数
      # 8208 是四叶玫瑰数
      # 9474 是四叶玫瑰数
```

# 题目3:逆序输出字符串

```python
# 写法1:切片方式
str = input("请输入字符串")
print(str[::-1])

# 写法2:循环转换
str = input("请输入字符串")
list = []
for x in range(len(str) -1,-1,-1):
    list.append(str)
print(''.join(list))

```
# 题目4:猜数字小游戏
需求分析:
1. 随机生成一个100以内的整数,共有10次机会
2. 开始游戏,输入猜测的数字
3. 如果猜小了,提示猜小了
4. 如果猜大了,提示猜大了
5. 猜对了,提示猜对了,并且结束游戏
6. 10次机会用完还没猜对,提示游戏结束,没有猜到。

```python
import random as rd

number = rd.randint(0,100)
for i in range(10):
    choice = int(input("请输入你要猜测的数字:"))
    if choice > number:
      print("你猜大了")
    elif choice < number:
      print("你猜小了")
    else:
      print("你猜对了,真棒!")
      print(f'你一共用了{i + 1}次机会')
      break
    print(f'还剩{9 - i}次机会')
else:
    print('游戏结束,你没有猜到')

```
# 题目5:百鸡百钱

需求分析:
1. 公鸡每只5元,母鸡每只3元,小鸡3只一元,现要求用100元钱买100只鸡(三种类型的鸡都要买),问公鸡、母鸡、小鸡各买几只?
2. 数学:
3. 设公鸡买了x只,母鸡买了y只,小鸡买了z只
4. x+y+z= 100
5. 5x+3y+z/3 = 100

算法思路
1. 以公鸡为突破点,公鸡5元一只,100元最多只能买20只,
2. 由于三种鸡都要买,所以公鸡数一定是小于20的。
3. 母鸡每只3元,100全拿来买母鸡,最多也不能超过33只
4. 设公鸡数为x,母鸡数为y,小鸡z只
5. 只要满足5x+3y+z/3=100 和 x+y+z==100 就可以输出此种组合的结果.

```python
count = 0
for x in range(1,20):
    for y in range(1,33):
      z = 100 - x -y
      if z > 0 and 5 * x + 3 * y + z / 3 == 100:
            count += 1
            print("="*60)
            print(f'第{count}种买法,公鸡买了{x}只,母鸡买了{y}只,小鸡买了{z}只')
            # == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
            # 第1种买法,公鸡买了4只,母鸡买了18只,小鸡买了78只
            # == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
            # 第2种买法,公鸡买了8只,母鸡买了11只,小鸡买了81只
            # == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
            # 第3种买法,公鸡买了12只,母鸡买了4只,小鸡买了84只

```


# 题目6:闰年问题升级版
> 输入年月日,输出该日期是否是闰年,并且输出该日期是此年份的第几天

闰年判断条件:
1. 能被4整除,并且不能被100整除
2. 能被400整除
3. 两个条件满足任意一个就为闰年

算法思路
1. 接收用户输入的年月日,创建保存12个月份天数的列表
2. 根据年份判断是否是闰年,如果是把二月份设为29天,否则把二月份设为28天
3. 根据月份和日期统计是当年的第几天

```python
year = int(input("请输入年份"))
month = int(input("请输入月份"))
day = int(input("请输入日期"))

date_list =
count_day = day
if year % 4 == 0 and year % 100 !=0 or year % 400 == 0:
    print(f'{year}年是闰年')
    date_list=29
else:
    print(f'{year}年是平年')
    date_list=28

for i in range(month-1):
    count_day += date_list

print(f'{year}年{month}月{day}日是当年的第{count_day}天')
```

# 题目7:猴子吃桃问题

需求分析:
1. 猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。
2. 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。
3. 以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。
4. 求原来它一共摘了多少个桃子。

1. 这题得倒着推。第10天还没吃,就剩1个,说明第9天吃完一半再吃1个还剩1个。
2. 假设第9天还没吃之前有桃子p个
3. 可得:p/2 - 1 = 1,得出第九天的桃子数p=4。
4. 以此类推,即可算出第一天摘了多少桃子.

算法思路
1. 第10天还没吃之前的桃子数量初始化p=1
2. 从9至1循环9次,根据上述公式反推为p=(p+1)*2可得
3. 第1天还没吃之前的桃子数量

```python
p = 1
print(f'第10天还剩下{p}个桃子')
for i in range(9,0,-1):
    p = (p + 1) * 2
    print(f'第{i}天还剩下{p}个桃子')
print(f'第一天一共摘了{p}个桃子')

# 第10天还剩下1个桃子
# 第9天还剩下4个桃子
# 第8天还剩下10个桃子
# 第7天还剩下22个桃子
# 第6天还剩下46个桃子
# 第5天还剩下94个桃子
# 第4天还剩下190个桃子
# 第3天还剩下382个桃子
# 第2天还剩下766个桃子
# 第1天还剩下1534个桃子
# 第一天一共摘了1534个桃子

```
# 题目8:冒泡排序

>冒泡排序算法由来
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”


>从前到后(即从下标较小的元素开始) 依次比较相邻元素的值,若发现比后一个值大则交换位置,使值较大的元素逐渐从前移向后部。



假设有一个列表 想升序

第一轮
- 比较 29 > 12 交换位置
-
- 比较 29 > 19 交换位置
-
- 比较 29 > 37 不大于 不交换,列表同上
- 比较 37 > 14 交换位置
-


第二轮
- 比较 12 > 19 不大于 不交换,列表同上
- 比较 19 > 29 不大于 不交换,列表同上
- 比较 29 > 14 交换位置
-


第三轮
- 比较 12 > 19 不大于 不交换,列表同上
- 比较 19 > 14 交换位置
-

第四轮
- 比较 12 > 14 不大于 不交换,列表同上
- 完成
-

```python
import numpy as np

pop_list = np.random.randint(100,size=6)

# pop_list =
# pop_list =

count = len(pop_list)
print('没排序之前的列表',pop_list)

for i in range(count-1):
    for j in range(count-i-1):
      if pop_list > pop_list: # 如果要降序就是改成 < 号
            pop_list,pop_list = pop_list,pop_list
print('排好序的列表为',pop_list)
# 排好序的列表为
# 排好序的列表为
```
# 题目9:二分查找法


二分法是一种效率比较高的搜索方法

> 回忆之前做过的猜数字的小游戏,预先给定一个小于100的正整数x,让你猜,猜测过程中给予大小判断的提示,问你怎样快速地猜出来? 我们之前做的游戏给定的是10次机会,如果我们学会二分查找法以后,不管数字是多少,最多只需要7次就能猜到数字

二分查找法

> 首先先猜50,如果猜对了,结束;如果猜大了,往小的方向猜,再猜25;如果猜小了,往大的方向猜,再猜75;...每猜测1次就去掉一半的数,这样我们就可以逐步逼近预先给定的数字.这种思想就是二分法。


二分法适用情况
1. 必须是有序的序列。
2. 对数据量大小有要求。
3. 数据量太小不适合二分查找,与直接遍历相比效率提升不明显。
4. 数据量太大也不适合用二分查找,因为数组需要连续的存储空间,若数据量太大,往往找不到存储如此大规模数据的连续内存空间



算法思路

1. 假设有一个有序列表
2. 请问数字11是否在此列表中,如果在它的索引值为多少?
3. 首先我们取有序列表的中间位置 27 和 11 进行比较 我们发现 11 是小于 27 的
4. 所以我们排除 27 右边的数字
5.
6. 接着我们取 位置中间的 7 和 11 比较 发现 11 是大于 7 的 所以我们排除 7 左边的数字
7. 最后我们取 11到22 的中间位置
8. 刚好到了11 这时候就可以返回 11 的索引值了,如果没有找到就提示不存在

> 第一种 纯算法的方式

```python
arr_list =
number = 11
count = 0
left = 0
right = len(arr_list)-1
while left<=right:
    middle = (left+right)//2
    count += 1
    if number > arr_list:
      left = middle +1
    elif number < arr_list:
      right = middle - 1
    else:
      print(f'数字{number}已找到,索引值为{middle}')
      break
else:
    print(f'数字{number}没有找到')
print(f'一共用了{count}次查找')

数字11已找到,索引值为2
一共用了3次查找

```

> 第二种 递归函数的方式

```python
arr_list =

def binary_search(number,left,right):
    if left <= right:
      middle = (left + right) // 2
      if number < arr_list:
            right = middle - 1
      elif number > arr_list:
            left = middle + 1
      else:
            return middle
      return binary_search(number,left,right)
    else:
      return -1

print(binary_search(11,0,len(arr_list)-1))
```
# 题目10:选择排序

>基本思想:从未排序的序列中找到一个最小的元素,放到第一位,再从剩余未排序的序列中找到最小的元素,放到第二位,依此类推,直到所有元素都排序完毕

- 若列表
- 先找到 1 最小 调换
-
- 接着是 2 最小 调换
-
- 接着是 3 最小 位置不变
- 接着是 4 最小 调换
-
- 接着是 5 最小 调换
-
- 接着是 6 最小 调换
-
- 接着是 7 最小 位置不变
- 接着是 8 最小 位置不变
- 接着是 9 最小 位置不变
- 接着是 10 最小 位置不变

```python
import random as rd

sec_list =
# sec_list =
length = len(sec_list)
print(f'未排序的列表为:{sec_list}')

for i in range(length -1):
    min_index = i
    for j in range(i + 1,length):
      if sec_list > sec_list:
            min_index = j
    sec_list,sec_list = sec_list,sec_list
    print(f'第{i+1}轮排好序是:{sec_list}')
print(f'最终排好序的列表为:{sec_list}')

# 未排序的列表为:
# 第1轮排好序是:
# 第2轮排好序是:
# 第3轮排好序是:
# 第4轮排好序是:
# 第5轮排好序是:
# 第6轮排好序是:
# 第7轮排好序是:
# 最终排好序的列表为:
```
# 题目11:剪刀石头布
>游戏开始,初始状态下用户和电脑都有100分,赢一局+10分,输一局-10分。当用户为0分时,游戏结束,提示游戏结束,比赛输了,当用户为200分时,游戏结束,提示游戏结束,赢得比赛、每轮比赛都输出当前的分数

>1代表剪刀 2代表石头 3代表布

```python
import random as rd

print('=' * 60)
print(' ' * 20, '剪刀石头布游戏')
print('1代表剪刀 2代表石头 3代表布')

game_info = {1: "剪刀", 2: "石头", 3: "布"}
score = 100

while True:
    robots_choice = rd.randint(1, 3)
    user_choice = input("请出拳")
    if user_choice not in '123':
      print('出拳错误,请重新出拳')
      continue
    user_choice = int(user_choice)
    print('*' * 60)
    print(f'电脑出{game_info}')
    print(f'你出{game_info}')
    print('*' * 60)
    if user_choice == 1 and robots_choice == 3 or user_choice == 2 \
            and robots_choice == 1 or user_choice == 3 and robots_choice == 2:
      score += 10
      print(f'你赢得本轮游戏,当前分数为{score}')
    elif user_choice == robots_choice:
      print(f'本轮游戏平局,当前分数为{score}')
    else:
      score -= 10
      print(f'你输了本轮游戏,当前分数{score}')
    if score >= 200:
      print('游戏结束,你赢得比赛')
      break
    elif score <= 0:
      print('游戏结束,你输了')
      break
```
# 题目12:快乐数
>在给定的数字下,该数字所有数位(digits)的平方和,得到的新数再次求所有数位的平方和,如此重复进行,最终结果必定为1

比如数字:19
- 1 * 1 = 1 9 * 9 = 81 = 1 + 81 = 82
- 8 * 8 = 642 * 2 = 4 = 64 + 4 = 68
- 6 * 6 = 368 * 8 = 64 = 36 + 64 = 100
- 1 + 0 + 0 = 1

```python
def sum_square(n):
    sum = 0
    for i in str(n):
      sum += int(i) ** 2
    return sum

list1 = []
n = int(input('请输入数字:'))
while sum_square(n) not in list1:
    n = sum_square(n)
    list1.append(n)

if n == 1:
    print('是快乐数')
else:
    print('不是快乐数')
```
# 题目13:猜年龄(一)
1. 小明带两个妹妹参加元宵灯会。别人问她们多大了,她们调皮地说:“我们俩的年龄之积是年龄之和的6倍“。
2. 小明又补充说:“她们可不是双胞胎,年龄差肯定也不超过8岁啊。“
3. 请你写出:小明的较小的妹妹的年龄。

```python
for i in range(1,100):
    for j in range(1,i):
      if i*j == 6*(i+j) and i-j<8:
            print(i,j)
# 15 10
```
# 题目14:猜年龄(二)
>美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。
他曾在1935~1936年应邀来中国清华大学讲学。
一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,
他回答说:“我年龄的立方是个4位数。我年龄的4次方是个6位数。
这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。“
请你推算一下,他当时到底有多年轻

```python
for i in range(10,30):
    i3 = str(i ** 3)
    i4 = str(i ** 4)
    if len(i3) == 4 and len(i4) == 6:
      if len(set(i3+i4)) == 10:
            print(i)
            print(i3 + i4)

# 18
# 5832104976
```
# 题目15:split算法实现

- split是python字符串内置的一个非常有用的方法它可以将一个字符串通过分隔符切成我们想要的列表比如现在我们有个字符串
- life-is-short-you-need-python
- 每一个单词之间使用横杆进行分割,当我们去调用字符串split的方法之后传入我们的分隔符横杆 - 那我们就会得到一个列表列表里面每个元素其实就是通过分隔符切出来的子字符串
- 那这个算法该怎么样去实现呢?python内置的split方法是通过C语言实现的,我们今天去写一个函数,去实现和split相同的功能
- 我们先来讲下算法该怎么样去实现这个算法需要我们对字符串进行迭代,我们先去定义一个初始化的指针,因为我们切片的时候需要从哪一个开始的位置进行切,所以我们先要初始化一个指针
- 我们可以定义一个指针变量,默认值为0,紧接着我们开始对字符串进行迭代,当碰到第一个分隔符的时候,我们是不是会获取到当前分隔符的索引,那这个时候,我们就把初始的指针开始到分隔符结束对字符串进行切片
- 因为我们字符串是遵守左闭右开的,你的结束索引写的是分隔符的索引,所以只会切到life,我们并把它添加到列表里面,紧接着添加完之后呢,我们需要把初始化的指针修改一下位置,修改到哪个地方呢?修改到我们第一次碰到的分隔符的下一个位置
- 也就是i,紧接着继续进行迭代,迭代之后发现第二个分隔符,是不是还有一个分隔符的索引,这个时候我们继续向字符串进行切片,切片的开始位置是你的i这个位置的指针,结束的位置是第二个 - 的指针,那遵循左闭右开,所以我们is这个单词,也可以添加进列表
- 就这样一直到最后呢,当我们去迭代到最后一个字符n的时候,发现后面是没有横杆分隔符了,这个时候我们需要进行处理一下,需要进行去判断一下,如果我们迭代到的字符是最后一个字符,那么我们进行切片的时候,就应该从哪个地方切呢?
- 从p开始 ,如果切到n,我们只能取到pytho,少切一个n,所以到n + 1的位置,好,知道这个流程我们就用代码去实现这个算法

```python
def split_s(string, sep="", num=0):
    split_words = []
    last_index = 0
    count = 0
    for index, char in enumerate(string):
      if count == num and num > 0:
            split_words.append(string)
            break
      if char == sep:
            split_words.append(string)
            last_index = index + 1
            count += 1
      elif index + 1 == len(string):
            split_words.append(string)
    return split_words

print(split_s("life-is-short-you-need-python",'-'))
# ['life', 'is', 'short', 'you', 'need', 'python']

print(split_s("life-is-short-you-need-python",'-',2))
# ['life', 'is', 'short-you-need-python']
```
# 题目16:大衍数列
>中国古代文献中,曾记载过“大衍数列”,主要用于解释中国传统文化中的太极衍生原理
它的前几项是:0、2、4、8、12、18、24、32、40、50...
其规律是:偶数项,是序号平方再除2,奇数项,是序号平方减1再除2。
打印大衍数列的前100项

```python
for x in range(1,101):
    if x % 2 == 0: # 偶数
      a = int((x ** 2) / 2)
    else: # 奇数
      a = int((x ** 2 - 1) / 2)
    print(a)
# 0
# 2
# 4
# 8
# 12
# 18
# 24
# 32
# 40
# 50
```
# 题目17:单词分析
- 小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词
- 现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这个字母出现的次数
- 其实就是让你输入一段字符串后,得到当前字符串出现最多的字母和它的次数
- 输入:HelloWorld
- 输出:
- l
-3
- 我们可以对当前的字符串进行循环迭代,然后把字符串当前每个字符当作key值,把它存到字典里面,如果当前key在字典里面,我们就让它加一,如果不在那我们就让它的次数初始化为1,最终我们再从字典找到次数最多的key值和value值

```python
def analyse_words(words):
    word_dict = {}
    for i in words:
      if i in word_dict:
            word_dict += 1
      else:
            word_dict = 1
    max_key = max(word_dict,key=word_dict.get)
    print(max_key)
    print(word_dict)
    # l
    # 3
analyse_words('helloworld')
```
# 题目18:利用栈打印菱形
> 输入边长n,打印对应边长的菱形

分析:
1. 打印几行
2. 每一行打印几个空格,几个星星
3. 前几行打印之前加入到栈,利用栈的后进先出原则打印后几行的内容

```python
def diamond(n):
    stack = []
    for i in range(1, 2 * n):
      if i <= n:
            p_str = ' ' * (n - i) + '*' * (2 * i - 1)
            if i != n:
                stack.append(p_str)
            print(p_str)
      else:
            print(stack.pop())

diamond(5)

# 为了区分我把空格换成了点
# ....*
# ...***
# ..*****
# .*******
# *********
# .*******
# ..*****
# ...***
# ....*
```
# 题目19:深入理解递归函数
>什么是递归函数?
递归函数就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身,每调用一次就进入新的一层。
递归函数必须有结束条件。

设计递归函数三要素:
1. 明确你这个函数想要干什么
2. 寻找递归结束条件
3. 找出函数的等价关系式

```python
def p(n):
    if n == 0:
      return
    print('递归前->',n)
    p(n-1)
    print('递归后->',n)
p(5)

# 递归前-> 5
# 递归前-> 4
# 递归前-> 3
# 递归前-> 2
# 递归前-> 1
# 递归后-> 1
# 递归后-> 2
# 递归后-> 3
# 递归后-> 4
# 递归后-> 5

```
# 题目20:斐波那契递归函数
>斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:
1、1、2、3、5、8、13、21、34、...
这个数列,前两项都是数字1,从第三项开始,每一项数字是前两项数字之和

>关系表达式【f(n) = f(n-1)+f(n-2)】

```python
def fib(n):
    if n<=2:
      return 1
    return fib(n-1)+fib(n-2)

print(fib(10)) # 55
print(fib(2)) # 1
```

> 递归与栈的关系
递归函数原理:每一次调用都会把当前调用压入到栈里,最后按照后进先出的原则,不停返回返回
由递归程序的执行过程,我们得知递归程序的调用是一层层向下的,而返回过程则恰好相反,一层层向上。

换个说法:最先一次的函数调用在最后返回,而最后一次的函数调用则是最先返回。这就跟栈的“后进先出”次序是一样的。因此,在实现递归调用的时候,通常就会使用栈来保存每一次调用的现场数据:
- 当一个函数被调用的时候,系统会把调用时的现场数据压入到系统调用栈,压入栈的现场数据称为栈帧。
- 当函数返回时,要从调用栈的栈顶取得返回地址,恢复现场,弹出栈帧,按地址返回。


# 题目21:三个数取最大数

> 己知数字a,b,c分别为10,6,18
找出a,b,c中最大的数字(不借助函数以及列表等方式)
我们知道函数max可以直接获取到最大值,或者可以把数字添加到列表里,通过排序也能获取到最大数字,我们单纯使用if分支来实现

```python
a, b, c = 10, 6, 18
if a > b:
    max_num = a
else:
    max_num = b
if max_num < c:
    max_num = c

print(max_num) # 18
```

# 题目22:因子之和“完数”
>什么是因子?
因子就是所有可以整除这个数的数字,包括1但不包括这个数自身。比如8的因子有1,2,4

>什么是完数?
一个数如果恰好等于它的因子之和,这个数就称为“完数”,打印输出1000以内的完数,例如6=1+2+3,6就是“完数

```python
def factor_sum(n):
    s_sum = 0
    for i in range(1, n):
      if n % i == 0:
            s_sum += i
    return s_sum

for j in range(1, 1000):
    if j == factor_sum(j):
      print(j)
      # 6
      # 28
      # 496
```

# 题目23:递归阶乘求和

> 一个正整数的阶乘(factorial)是所有小于及等于该数的正整数之积,并且0的阶乘为1

```
如5!=1*2*3*4*5
计算1!+2!+3!+4!+5!+…+10!
关系表达式【f(n) = n*f(n-1)】
```

```python
def factor(n):
    if n < 2:
      return 1
    return n * factor(n - 1)


s_sum = 0
for i in range(1, 11):
    s_sum += factor(i)
print(s_sum)# 4037913
```

# 题目24:有效的括号
> 给定一个只包括'(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:
- 左括号必须用相同类型的右括号闭合
- 左括号必须以正确的顺序闭合
- 空字符串可被认为是有效字符串


示例 1:
输入:"()"
输出:True

示例 2:
输入:"()[]{}"
输出:True

示例 3:
输入:"(]"
输出:False

示例 4:
输入:"([)]"
输出:False


>解法一:字符串替换法
在字符串中找成对的()、[]、{},找到后替换成空
使用while循环,不停判断是否存在成对的小括号中括号大括号,如果存在就使用replace替换成空
直到无法再替换的时候,再判断下当前的字符串是否为空,如果为空说明字符串是有效的,如果不为空说明字符串是无效的

```python
def valid_str(string):
    if len(string) % 2 == 1:
      return False
    while '()' in string or '[]' in string or '{}' in string:
      string = string.replace('()', '')
      string = string.replace('[]', '')
      string = string.replace('{}', '')
    return string == ''

print(valid_str('()'))# True
print(valid_str('()[]{}'))# True
print(valid_str('()[]{[()]}'))# True
print(valid_str('()[]{[(}]}'))# False
```

>解法二:利用栈的后进先出原则
先去定义一个空栈,对当前栈进行循环遍历,遇到左括号我们就把当前的左括号添加到栈里面,遇到右括号,我们就和栈顶元素进行比对
看它们是不是成对的括号,如果是,就把当前的元素出栈,直到字符串遍历结束之后,我们再来看下字符串是不是空的,如果是空的说明字符串是有效的,如果不为空说明字符串是无效的

```python
def valid_str(string):
    if len(string) % 2 == 1:
      return False
    stack = []
    char_dict = {
      ')': '(',
      '}': '{',
      ']': '['
    }
    for char in string:
      if char in char_dict:
            # 右括号
            if not stack or char_dict != stack.pop():
                return False
      else:
            # 左括号
            stack.append(char)
    return not stack

print(valid_str('(){}[({[]})]'))# True
print(valid_str('(){}[({[)})]'))# False
print(valid_str(''))# True
```

# 题目25:回文数的两种解法

>回文数是指正序(从左向右)和倒序(从右向左)都是一样的整数。例如,1221是回文,而1222不是。

解法一:通过逆转字符串进行比对

```python
def is_palindrome(x):
    if x < 0 or x > 0 and x % 10 == 0:
      return False
    str_x = str(x)
    return str_x == str_x[::-1]

print(is_palindrome(121))# True
print(is_palindrome(120))# False
```

解法二:反转一半数字和前半部分的数字进行比较

流程
- 对于整数x,后半部分reverted
- 每次循环x%10拿到末尾数字
- 然后x/10去除末尾的数字
- 循环结束条件x<=reverted

数字长度(奇数)
12321

数字长度(偶数)
1221

```python
def is_palindrome(x):
    if x < 0 or x > 0 and x % 10 == 0:
      return False
    reverted = 0
    while x > reverted:
      # 我们看下 1221
      # 第一次循环我们需要把末尾数字1取出来 第二次取末尾数字2 我们需要把21变成12
      reverted = reverted * 10 + x % 10
      # 把x的末尾数字删除掉
      x //= 10
    return x == reverted or x == reverted // 10

print(is_palindrome(1221))# True
print(is_palindrome(1223))# False
print(is_palindrome(123321))# True
```

特百惠 发表于 2022-9-17 18:26

这教程牛逼,收藏了,前排啊!!非常感谢大佬

52ECHO 发表于 2022-9-19 09:59

本帖最后由 52ECHO 于 2022-9-19 14:26 编辑


# Windows bat 命令行解法
既然置顶了,干脆把新做的练习都更新这楼.

#### 使用方法:
创建一个.txt文件,复制粘贴代码,另存为ANSI编码,重命名文件扩展名为.bat

## 题目1:水仙花数
水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(Armstrong number),
水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身。例如:1^3 + 5^3+ 3^3 = 153。
```
:NarcissisticNumber
setlocal EnableDelayedExpansion
FOR /L %%a in (1,1,9) do FOR /L %%b in (0,1,9) do FOR /L %%c in (0,1,9) do (
      SET /A abc=%%a*%%a*%%a+%%b*%%b*%%b+%%c*%%c*%%c
      IF !abc!==%%a%%b%%c ECHO.%%a%%b%%c 是水仙花数
)
endlocal
```


## 题目2:四叶玫瑰数
四叶玫瑰数是4位数的自幂数。自幂数是指一个 n 位数,它的每个位上的数字的 n 次幂之和等于它本身。
(例如:当n为3时,有1^3 + 5^3 + 3^3 = 153,153即是n为3时的一个自幂数,3位数的自幂数被称为水仙花数)。
```
:FourLeavesRose
setlocal EnableDelayedExpansion
FOR /L %%a in (1,1,9) do FOR /L %%b in (0,1,9) do FOR /L %%c in (0,1,9) do FOR /L %%d in (0,1,9) do (
      SET /A abcd=%%a*%%a*%%a*%%a+%%b*%%b*%%b*%%b+%%c*%%c*%%c*%%c+%%d*%%d*%%d*%%d
      IF !abcd!==%%a%%b%%c%%d ECHO.%%a%%b%%c%%d 是四叶玫瑰数
)
endlocal
```


## 题目3:逆序输出字符串
```
:ReverseString
SET /p str="请输入字符串:"
SET rts=
ECHO.正序字符串:%str%
:StringBackwardX
SET rts=%str:~,1%%rts%
SET str=%str:~1%
IF not "%str%"=="" GOTO:StringBackwardX
ECHO.逆序字符串:%rts%
```

wuxiuxin 发表于 2022-9-20 07:40

斐波那契数列,主要用于测试设备性能,用整个函数之间的运算
package main

/*
题目20:斐波那契递归函数
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:
1、1、2、3、5、8、13、21、34、...
这个数列,前两项都是数字1,从第三项开始,每一项数字是前两项数字之和

关系表达式【f(n) = f(n-1)+f(n-2)】
*/
func Feibonai(n int) (y int) {
        if n <= 2 {
                return 1
        }
        return Feibonai(n-1) + Feibonai(n-2)

}
/*
运行结果
55
1
*/

OVVO 发表于 2022-10-4 02:56

易语言语法的25个练习题
https://www.52pojie.cn/thread-1695470-1-1.html
(出处: 吾爱破解论坛)

limuyang 发表于 2022-10-14 13:51

我用易语言写了一遍。(我是有多无聊。)
共分了4个程序集

程序集一
.版本 2
.支持库 spec
.支持库 eAPI

.程序集 程序集1

.子程序 _启动子程序, 整数型, , 本子程序在程序启动后最先执行

' 题目1_水仙花数 ()
' 题目2_四叶玫瑰数 ()
' 题目3_逆序输出字符串 ()
' 题目4_猜数字小游戏 ()
' 题目5_百鸡百钱 ()
' 题目6_闰年问题升级版 ()
' 题目7_猴子吃桃问题 ()
' 题目8_冒泡排序 ()
' 题目9_二分查找法 ()
' 题目10_选择排序 ()
' 题目11_剪刀石头布 ()
' 题目12_快乐数 ()
' 题目13_猜年龄1 ()
' 题目14_猜年龄2 ()
' 题目15_split算法实现 ()
' 题目16_大衍数列 ()
' 题目17_单词分析 ()
' 题目18_打印菱形 ()
' 题目19_深入理解递归函数 ()
' 题目20_斐波那契递归函数 ()
' 题目21_三个数取最大数 ()
' 题目22_因子之和_完数 ()
' 题目23_递归阶乘求和 ()
' 题目24_有效的括号 ()
' 题目25_回文数的两种解法 ()


返回 (0)' 可以根据您的需要返回任意数值

.子程序 题目1_水仙花数
.局部变量 i, 整数型

' 水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(Armstrong number),水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身。例如:1^3 + 5^3+ 3^3 = 153。
i = 100
.判断循环首 (i < 1000)
    .如果真 (是否为自幂数 (i))
      调试输出 (i)
    .如果真结束
    i = i + 1
.判断循环尾 ()

.子程序 题目2_四叶玫瑰数
.局部变量 i, 整数型

' 四叶玫瑰数是4位数的自幂数。自幂数是指一个 n 位数,它的每个位上的数字的 n 次幂之和等于它本身。(例如:当n为3时,有1^3 + 5^3 + 3^3 = 153,153即是n为3时的一个自幂数,3位数的自幂数被称为水仙花数)。
i = 1000
.判断循环首 (i < 10000)
    .如果真 (是否为自幂数 (i))
      调试输出 (i)
    .如果真结束
    i = i + 1
.判断循环尾 ()

.子程序 题目3_逆序输出字符串, , , 题目3:逆序输出字符串
.局部变量 str, 文本型
.局部变量 逆序, 文本型
.局部变量 str_zjj, 字节集
.局部变量 i
.局部变量 ret, 文本型

str = 标准输入 ()
str_zjj = 到字节集 (str)
i = 取字节集长度 (str_zjj)
.判断循环首 (i > 0)
    .如果 (str_zjj < 128)
      .如果 (str_zjj = 10 且 i - 1 > 0)
            ret = ret + 字符 (str_zjj ) + 字符 (str_zjj )
            i = i - 2
      .否则
            ret = ret + 字符 (str_zjj )
            i = i - 1
      .如果结束

    .否则
      .如果 (i - 1 > 0)
            ret = ret + 字符 (str_zjj ) + 字符 (str_zjj )
            i = i - 2
      .否则
            ret = ret + 字符 (str_zjj )
            i = i - 1
      .如果结束

    .如果结束

.判断循环尾 ()
调试输出 (ret)


.子程序 题目4_猜数字小游戏
.局部变量 随机数
.局部变量 i, 整数型
.局部变量 输入的数

' 随机生成一个100以内的整数,共有10次机会
' 开始游戏,输入猜测的数字
' 如果猜小了,提示猜小了
' 如果猜大了,提示猜大了
' 猜对了,提示猜对了,并且结束游戏
' 10次机会用完还没猜对,提示游戏结束,没有猜到。
置随机数种子 ()
随机数 = 取随机数 (1, 100)
.计次循环首 (10, i)
    标准输出 (, “请输入你猜的数字:”)
    输入的数 = 到整数 (标准输入 ())
    .如果真 (输入的数 = 随机数)
      标准输出 (, “猜对了,结束游戏!” + #换行符)
      标准输出 (, “按enter结束”)
      标准输入 ()
      返回 ()
    .如果真结束
    .如果 (输入的数 > 随机数)
      标准输出 (, “猜大了!” + #换行符)
    .否则
      标准输出 (, “猜小了!” + #换行符)
    .如果结束


.计次循环尾 ()
调试输出 (“游戏结束,你没有猜到!”)


.子程序 题目5_百鸡百钱
.局部变量 公鸡
.局部变量 母鸡
.局部变量 小鸡
.局部变量 i, 整数型

' 公鸡每只5元,母鸡每只3元,小鸡3只一元,现要求用100元钱买100只鸡(三种类型的鸡都要买),问公鸡、母鸡、小鸡各买几只?
' 数学:
' 设公鸡买了x只,母鸡买了y只,小鸡买了z只
' x+y+z= 100
' 5x+3y+z/3 = 100
.计次循环首 (100 ÷ 5, 公鸡)
    .计次循环首 (100 ÷ 3, 母鸡)
      .计次循环首 (100 × 3, 小鸡)
            .如果真 (公鸡 + 母鸡 + 小鸡 = 100 且 5 × 公鸡 + 3 × 母鸡 + 小鸡 ÷ 3 = 100)
                i = i + 1
                调试输出 (格式化文本 (“第%d种买法,公鸡买了%d只,母鸡买了%d只,小鸡买了%d只”, i, 公鸡, 母鸡, 小鸡))

            .如果真结束



      .计次循环尾 ()
    .计次循环尾 ()
.计次循环尾 ()

.子程序 题目12_快乐数
.局部变量 i, 整数型

.计次循环首 (100, i)
    调试输出 (i, 选择 (是否为快乐数 (i), “是快乐数!”, “不是快乐数!”))

.计次循环尾 ()


.子程序 题目15_split算法实现
.局部变量 str, 文本型
.局部变量 待分割文本, 文本型
.局部变量 用作分割的文本, 文本型
.局部变量 要返回的子文本数目, 整数型
.局部变量 返回的文本数组, 文本型, , "0"

str = “---life-is-short--you--need--python”
用作分割的文本 = “i”
要返回的子文本数目 = 1
split算法实现 (str, 用作分割的文本, 要返回的子文本数目, 返回的文本数组)
调试输出 (返回的文本数组)
返回 ()


.子程序 题目24_有效的括号

调试输出 (是否为有效的括号 (“(){}[({[]})]”))' 真
调试输出 (是否为有效的括号 (“(){}[({[)})]”))' 假
调试输出 (是否为有效的括号 (“”))' 假


.子程序 题目6_闰年问题升级版
.局部变量 str, 文本型
.局部变量 输入的时间, 日期时间型
.局部变量 年, 整数型
.局部变量 闰年, 逻辑型
.局部变量 天数, 整数型

' 输入年月日,输出该日期是否是闰年,并且输出该日期是此年份的第几天
.判断循环首 (输入的时间 = )
    标准输出 (, “请输入年月日(格式:YYYYMMDD):”)
    str = 标准输入 ()
    .如果 (到时间 (str) = 或 取文本长度 (str) ≠ 8)
      标准输出 (, “格式不对,请重新输入!”)
    .否则
      输入的时间 = 到时间 (str)
    .如果结束

.判断循环尾 ()
.如果真 (取年份 (输入的时间) % 4 = 0 且 取年份 (输入的时间) % 100 ≠ 0)
    闰年 = 真
.如果真结束
.如果真 (取年份 (输入的时间) % 400 = 0)
    闰年 = 真
.如果真结束
天数 = 取时间间隔 (输入的时间, 到时间 (到文本 (取年份 (输入的时间)) + “0101”), #日) + 1
调试输出 (格式化文本 (“%d年是%s,%s是当年的第%d天”, 取年份 (输入的时间), 选择 (闰年, “闰年”, “平年”), 到文本 (输入的时间), 天数))



.子程序 题目7_猴子吃桃问题
.局部变量 i, 整数型
.局部变量 j, 整数型
.局部变量 桃子, 整数型
.局部变量 算法, 整数型

' 需求分析:
' 猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。
' 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。
' 以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。
' 求原来它一共摘了多少个桃子。
置随机数种子 ()
算法 = 取随机数 (1, 2)
.如果真 (算法 = 1)
    .判断循环首 (桃子 ≥ 0)
      桃子 = 桃子 + 1
      i = 桃子
      .计次循环首 (9, j)
            .如果真 (i % 2 = 1)
                跳出循环 ()
            .如果真结束
            i = i - i ÷ 2 - 1
            .如果真 (j = 9 且 i = 1)
                调试输出 (格式化文本 (“猴子第一天摘下%d个桃子”, 桃子))
                返回 ()
            .如果真结束

      .计次循环尾 ()
    .判断循环尾 ()

.如果真结束
.如果真 (算法 = 2)
    桃子 = 1
    .计次循环首 (9, i)
      桃子 = (桃子 + 1) × 2
    .计次循环尾 ()
    调试输出 (格式化文本 (“猴子第一天摘下%d个桃子”, 桃子))
.如果真结束


.子程序 题目8_冒泡排序
.局部变量 int0, 整数型, , "0"
.局部变量 i, 整数型

' 冒泡排序算法由来
' 这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”
' 从前到后(即从下标较小的元素开始) 依次比较相邻元素的值,若发现比后一个值大则交换位置,使值较大的元素逐渐从前移向后部。
int0 = { 29, 12, 19, 37, 14 }
.计次循环首 (取数组成员数 (int0), i)
    .计次循环首 (取数组成员数 (int0) - i, )
      .如果真 (int0 > int0 )
            交换变量 (int0 , int0 )
      .如果真结束

    .计次循环尾 ()
.计次循环尾 ()
调试输出 (int0)

.子程序 题目9_二分查找法
.局部变量 int0, 整数型, , "0"
.局部变量 num, 整数型
.局部变量 数组个数, 整数型
.局部变量 本次位置, 整数型
.局部变量 最小位置, 整数型
.局部变量 最大位置, 整数型
.局部变量 i, 整数型

' 二分法是一种效率比较高的搜索方法

' 回忆之前做过的猜数字的小游戏,预先给定一个小于100的正整数x,让你猜,猜测过程中给予大小判断的提示,问你怎样快速地猜出来? 我们之前做的游戏给定的是10次机会,如果我们学会二分查找法以后,不管数字是多少,最多只需要7次就能猜到数字

' 二分查找法

' 首先先猜50,如果猜对了,结束;如果猜大了,往小的方向猜,再猜25;如果猜小了,往大的方向猜,再猜75;...每猜测1次就去掉一半的数,这样我们就可以逐步逼近预先给定的数字.这种思想就是二分法。

' 二分法适用情况

' 必须是有序的序列。
' 对数据量大小有要求。
' 数据量太小不适合二分查找,与直接遍历相比效率提升不明显。
' 数据量太大也不适合用二分查找,因为数组需要连续的存储空间,若数据量太大,往往找不到存储如此大规模数据的连续内存空间

' 假设有一个有序列表
' 请问数字11是否在此列表中,如果在它的索引值为多少?
' 首先我们取有序列表的中间位置 27 和 11 进行比较 我们发现 11 是小于 27 的
' 所以我们排除 27 右边的数字
'
' 接着我们取 位置中间的 7 和 11 比较 发现 11 是大于 7 的 所以我们排除 7 左边的数字
' 最后我们取 11到22 的中间位置
' 刚好到了11 这时候就可以返回 11 的索引值了,如果没有找到就提示不存在


int0 = { 5, 7, 11, 22, 27, 33, 39, 52, 58 }' 假设升序排列
.' 计次循环首 (100, i)
    ' 加入成员 (int0, i)
.' 计次循环尾 ()
' 调试输出 (int0)
num = 53
数组个数 = 取数组成员数 (int0)
最大位置 = 数组个数
最小位置 = 1
i = 0
.判断循环首 (数组个数 > 0)
    i = i + 1
    本次位置 = (最大位置 - 最小位置 + 1) \ 2 + 最小位置
    调试输出 (最小位置, 最大位置, 本次位置, int0 [本次位置])
    .如果真 (int0 [本次位置] = num)
      调试输出 (格式化文本 (“第%d次查找,在第%d个位置找到%d”, i, 本次位置, int0 [本次位置]))
      返回 ()
    .如果真结束
    .如果真 (int0 [本次位置] < num)
      最小位置 = 本次位置 + 1
    .如果真结束
    .如果真 (int0 [本次位置] > num)
      最大位置 = 本次位置 - 1
    .如果真结束
    .如果真 (最小位置 ≥ 最大位置)
      .如果真 (int0 [最小位置] = num)
            调试输出 (格式化文本 (“第%d次查找,在第%d个位置找到%d”, i, 最小位置, int0 [最小位置]))
            返回 ()
      .如果真结束
      .如果真 (int0 [最大位置] = num)
            调试输出 (格式化文本 (“第%d次查找,在第%d个位置找到%d”, i, 最大位置, int0 [最大位置]))
            返回 ()
      .如果真结束
      调试输出 (“找不到”)
      返回 ()
    .如果真结束

.判断循环尾 ()

.子程序 题目10_选择排序
.局部变量 list, 整数型, , "0"
.局部变量 总成员数, 整数型
.局部变量 i, 整数型
.局部变量 j, 整数型
.局部变量 最小的, 整数型

' 基本思想:从未排序的序列中找到一个最小的元素,放到第一位,再从剩余未排序的序列中找到最小的元素,放到第二位,依此类推,直到所有元素都排序完毕
list = { 91, 30, 93, 98, 26, 98, 20, 90 }
总成员数 = 取数组成员数 (list)
.计次循环首 (总成员数, i)
    最小的 = i
    .计次循环首 (总成员数 - i, j)
      .如果真 (list [最小的] > list )
            最小的 = i + j
      .如果真结束

    .计次循环尾 ()
    .如果真 (i ≠ 最小的)
      交换变量 (list , list [最小的])
    .如果真结束

.计次循环尾 ()
调试输出 (list)


.子程序 题目11_剪刀石头布
.局部变量 用户分数, 整数型
.局部变量 电脑分数, 整数型
.局部变量 用户出拳, 整数型
.局部变量 电脑出拳, 整数型
.局部变量 str, 文本型

' 游戏开始,初始状态下用户和电脑都有100分,赢一局+10分,输一局-10分。
' 当用户为0分时,游戏结束,提示游戏结束,比赛输了,当用户为200分时,游戏结束,提示游戏结束,赢得比赛、每轮比赛都输出当前的分数
用户分数 = 100
电脑分数 = 100
标准输出 (, “剪刀石头布游戏开始!1代表剪刀 2代表石头 3代表布” + #换行符)
置随机数种子 ()
.判断循环首 (用户分数 > 0 且 电脑分数 > 0)
    电脑出拳 = 取随机数 (1, 3)
    标准输出 (, 格式化文本 (“你现在的分数%d,电脑分数%d。” + #换行符 + “请出拳:”, 用户分数, 电脑分数))
    用户出拳 = 0
    .判断循环首 (用户出拳 = 0)
      str = 标准输入 ()
      .如果真 (str = “剪刀” 或 str = “1”)
            用户出拳 = 1
      .如果真结束
      .如果真 (str = “石头” 或 str = “2”)
            用户出拳 = 2
      .如果真结束
      .如果真 (str = “布” 或 str = “3”)
            用户出拳 = 3
      .如果真结束
      .如果真 (用户出拳 = 0)
            标准输出 (, “出拳错误,请重新出拳(1代表剪刀 2代表石头 3代表布):”)
      .如果真结束

    .判断循环尾 ()
    标准输出 (, “电脑出拳为:” + 题目11_剪刀石头布_数字转文本 (电脑出拳) + “,你出拳为:” + 题目11_剪刀石头布_数字转文本 (用户出拳) + #换行符)
    .如果真 (用户出拳 = 电脑出拳)
      标准输出 (, “平局”)
      到循环尾 ()
    .如果真结束
    .如果真 (用户出拳 - 电脑出拳 = 1 或 用户出拳 - 电脑出拳 = -2)
      标准输出 (, “你赢了”)
      用户分数 = 用户分数 + 10
      电脑分数 = 电脑分数 - 10
      到循环尾 ()
    .如果真结束
    .如果真 (用户出拳 - 电脑出拳 = -1 或 用户出拳 - 电脑出拳 = 2)
      标准输出 (, “你输了”)
      用户分数 = 用户分数 - 10
      电脑分数 = 电脑分数 + 10
      到循环尾 ()
    .如果真结束

    标准输出 (, “其他异常”)

.判断循环尾 ()

.如果真 (用户分数 = 0)
    调试输出 (“提示游戏结束,比赛输了。”)
.如果真结束
.如果真 (用户分数 = 200)
    调试输出 (“游戏结束,赢得比赛!”)
.如果真结束


.子程序 题目13_猜年龄1
.局部变量 小明, 整数型
.局部变量 妹妹_小, 整数型
.局部变量 妹妹_大, 整数型

' 小明带两个妹妹参加元宵灯会。别人问她们多大了,她们调皮地说:“我们俩的年龄之积是年龄之和的6倍“。
' 小明又补充说:“她们可不是双胞胎,年龄差肯定也不超过8岁啊。“
' 请你写出:小明的较小的妹妹的年龄。

.计次循环首 (10000, 妹妹_大)
    .计次循环首 (10000, 妹妹_小)
      .如果真 (妹妹_大 > 妹妹_小 且 妹妹_大 - 妹妹_小 ≤ 8 且 妹妹_小 × 妹妹_大 = (妹妹_小 + 妹妹_大) × 6)
            调试输出 (妹妹_小)
      .如果真结束

    .计次循环尾 ()
.计次循环尾 ()




.子程序 题目14_猜年龄2
.局部变量 维纳, 整数型
.局部变量 数组1, 整数型, , "0"
.局部变量 数组2, 整数型, , "0"
.局部变量 j, 整数型
.局部变量 i, 整数型

' 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。
' 他曾在1935~1936年应邀来中国清华大学讲学。
' 一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,
' 他回答说:“我年龄的立方是个4位数。我年龄的4次方是个6位数。
' 这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。“
' 请你推算一下,他当时到底有多年轻
.计次循环首 (100, 维纳)
    .如果真 (求位数 (求次方 (维纳, 3), 数组1) = 4 且 求位数 (求次方 (维纳, 4), 数组2) = 6)
      加入成员 (数组1, 数组2)
      数组2 = 数组1
      .如果真 (取数组成员数 (数组1) = 10)
            ' 调试输出 (数组1)
            .计次循环首 (10, j)
                .计次循环首 (11 - j, i)
                  .如果真 (j - 1 = 数组1 )
                        删除成员 (数组1, i, 1)
                        ' 调试输出 (数组1)
                        跳出循环 ()
                  .如果真结束

                .计次循环尾 ()
            .计次循环尾 ()
            .如果真 (取数组成员数 (数组1) = 0)
                调试输出 (维纳, 数组2)
            .如果真结束

      .如果真结束

    .如果真结束

.计次循环尾 ()


.子程序 题目16_大衍数列
.局部变量 i, 整数型
.局部变量 ret, 文本型
.局部变量 结果, 整数型

' 中国古代文献中,曾记载过“大衍数列”,主要用于解释中国传统文化中的太极衍生原理
' 它的前几项是:0、2、4、8、12、18、24、32、40、50...
' 其规律是:偶数项,是序号平方再除2,奇数项,是序号平方减1再除2。
' 打印大衍数列的前100项
.计次循环首 (100, i)
    结果 = 选择 (i % 2 = 1, (i × i - 1) ÷ 2, i × i ÷ 2)
    ret = ret + 到文本 (结果) + “、”
.计次循环尾 ()
调试输出 (ret)

.子程序 题目17_单词分析
.局部变量 str, 文本型
.局部变量 长度, 整数型
.局部变量 i, 整数型
.局部变量 临时文本i, 文本型
.局部变量 j, 整数型
.局部变量 临时文本j, 文本型
.局部变量 zjj, 字节集
.局部变量 最大值, 整数型
.局部变量 最大值的文本, 文本型, , "0"
.局部变量 标记, 整数型

' 小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词
' 现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这个字母出现的次数
' 其实就是让你输入一段字符串后,得到当前字符串出现最多的字母和它的次数
' 输入:HelloWorld
' 输出:
' l
' 3
' 我们可以对当前的字符串进行循环迭代,然后把字符串当前每个字符当作key值,把它存到字典里面,如果当前key在字典里面,我们就让它加一,如果不在那我们就让它的次数初始化为1,最终我们再从字典找到次数最多的key值和value值


str = “HelloWorld”
str = 到小写 (str)
长度 = 取文本长度 (str)
zjj = 取空白字节集 (长度)
.计次循环首 (长度, i)
    临时文本i = 取文本中间 (str, i, 1)
    .计次循环首 (长度, j)
      临时文本j = 取文本中间 (str, j, 1)
      .如果真 (临时文本i = 临时文本j)
            zjj = zjj + 1
      .如果真结束

    .计次循环尾 ()
.计次循环尾 ()
.计次循环首 (长度, i)
    .如果真 (zjj > 最大值)
      最大值 = zjj
    .如果真结束

.计次循环尾 ()
.计次循环首 (长度, i)
    .如果真 (zjj = 最大值)
      临时文本i = 取文本中间 (str, i, 1)
      标记 = 0
      .计次循环首 (取数组成员数 (最大值的文本), j)
            .如果真 (最大值的文本 = 临时文本i)
                标记 = 1
            .如果真结束

      .计次循环尾 ()
      .如果真 (标记 = 0)
            加入成员 (最大值的文本, 临时文本i)
      .如果真结束

    .如果真结束

.计次循环尾 ()
调试输出 (最大值的文本, 最大值)


.子程序 题目18_打印菱形
.局部变量 n, 整数型
.局部变量 ret, 文本型
.局部变量 i, 整数型
.局部变量 星星数量, 整数型
.局部变量 空格数量, 整数型

' 输入边长n,打印对应边长的菱形
' 分析:
' 打印几行
' 每一行打印几个空格,几个星星
标准输出 (, “输入边长:”)
.判断循环首 (n < 1)
    n = 到整数 (标准输入 ())
.判断循环尾 ()
.计次循环首 (2 × n - 1, i)
    .如果 (i ≤ n)
      星星数量 = i × 2 - 1
      空格数量 = n - i
    .否则
      星星数量 = 2 × n - 1 - (i - n) × 2
      空格数量 = i - n
    .如果结束
    ret = #换行符 + 取重复文本 (空格数量, “ ”) + 取重复文本 (星星数量, “*”) + ret
.计次循环尾 ()
调试输出 (ret + #换行符)
标准输出 (, ret + #换行符 + “按enter结束”)
标准输入 ()


.子程序 题目19_深入理解递归函数
.局部变量 n, 整数型

' 什么是递归函数?
' 递归函数就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身,每调用一次就进入新的一层。

' 递归函数必须有结束条件。

' 设计递归函数三要素:
' 明确你这个函数想要干什么
' 寻找递归结束条件
' 找出函数的等价关系式

题目19_深入理解递归函数_简单的递归 (5)


.子程序 题目20_斐波那契递归函数
.局部变量 n, 整数型
.局部变量 ret, 文本型

' 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:
' 1、1、2、3、5、8、13、21、34、...
' 这个数列,前两项都是数字1,从第三项开始,每一项数字是前两项数字之和
' 关系表达式【f(n) = f(n-1)+f(n-2)】
.计次循环首 (10, n)
    ret = ret + 到文本 (题目20_斐波那契递归函数_调用 (n)) + “、”
.计次循环尾 ()
调试输出 (ret)


.子程序 题目21_三个数取最大数
.局部变量 a
.局部变量 b
.局部变量 c
.局部变量 max

' 己知数字a,b,c分别为10,6,18
' 找出a,b,c中最大的数字(不借助函数以及列表等方式)
' 我们知道函数max可以直接获取到最大值,或者可以把数字添加到列表里,通过排序也能获取到最大数字,我们单纯使用if分支来实现
a = 1
b = 3
c = 2

.如果 (a > b)
    max = a
.否则
    max = b
.如果结束
.如果真 (c > max)
    max = c
.如果真结束
调试输出 (max)


.子程序 题目22_因子之和_完数
.局部变量 i, 整数型
.局部变量 因子数组, 整数型, , "0"
.局部变量 j, 整数型
.局部变量 Sum, 整数型

' 什么是因子?
' 因子就是所有可以整除这个数的数字,包括1但不包括这个数自身。比如8的因子有1,2,4

' 什么是完数?
' 一个数如果恰好等于它的因子之和,这个数就称为“完数”,打印输出1000以内的完数,例如6=1+2+3,6就是“完数

.计次循环首 (1000, i)
    .如果真 (取因子 (i, 因子数组))
      Sum = 0
      .计次循环首 (取数组成员数 (因子数组), j)
            Sum = Sum + 因子数组
      .计次循环尾 ()
      .如果真 (i = Sum)
            调试输出 (i)
      .如果真结束

    .如果真结束

.计次循环尾 ()

.子程序 题目23_递归阶乘求和
.局部变量 i, 整数型
.局部变量 sum
.局部变量 n
.局部变量 算法

' 一个正整数的阶乘(factorial)是所有小于及等于该数的正整数之积,并且0的阶乘为1
' 如5!=1*2*3*4*5
' 计算1!+2!+3!+4!+5!+…+10!
' 关系表达式【f(n) = n*f(n-1)】
置随机数种子 ()
算法 = 取随机数 (1, 2)
n = 10

.如果真 (算法 = 1)
    .计次循环首 (n, i)
      sum = sum + 求阶乘_递归 (i)
    .计次循环尾 ()
.如果真结束
.如果真 (算法 = 2)
    sum = 求阶乘和 (n)
.如果真结束
调试输出 (sum)


.子程序 题目25_回文数的两种解法
.局部变量 n, 整数型
.局部变量 int0, 整数型, , "0"
.局部变量 反转后, 整数型, , "0"
.局部变量 长度, 整数型
.局部变量 i, 整数型
.局部变量 j, 整数型
.局部变量 标记, 整数型

' 回文数是指正序(从左向右)和倒序(从右向左)都是一样的整数。例如,1221是回文,而1222不是。
置随机数种子 ()
n = 取随机数 (0, 99999)
长度 = 求位数 (n, int0)
' 解法一:通过逆转字符串进行比对
标记 = 0
.计次循环首 (长度, i)
    .如果真 (int0 ≠ int0 [长度 - i + 1])
      标记 = 1
      跳出循环 ()
    .如果真结束

.计次循环尾 ()
.如果 (标记 = 0)
    调试输出 (“解法一:” + 到文本 (n) + “回文数”)
.否则
    调试输出 (“解法一:” + 到文本 (n) + “不是回文数”)
.如果结束
' 解法二:只比较一半的数字
标记 = 0
.计次循环首 (长度 \ 2, i)
    .如果真 (int0 ≠ int0 [长度 - i + 1])
      标记 = 1
      跳出循环 ()
    .如果真结束

.计次循环尾 ()
.如果 (标记 = 0)
    调试输出 (“解法二:” + 到文本 (n) + “回文数”)
.否则
    调试输出 (“解法二:” + 到文本 (n) + “不是回文数”)
.如果结束




程序集二
.版本 2
.支持库 spec

.程序集 数字相关

.子程序 求位数, 整数型
.参数 正整数
.参数 返回的数字, 整数型, 参考 数组, 逆序返回每一位上面的数字,依次为 个位、十位、百位
.局部变量 位数
.局部变量 tmp

tmp = 正整数
重定义数组 (返回的数字, 假, 0)
.判断循环首 (tmp ≠ 0)
    加入成员 (返回的数字, tmp % 10)
    tmp = tmp ÷ 10
    位数 = 位数 + 1
.判断循环尾 ()
.如果真 (位数 = 0)
    位数 = 1
.如果真结束
返回 (位数)


.子程序 是否为自幂数, 逻辑型
.参数 c
.局部变量 整数位数, 整数型
.局部变量 每一位数字, 整数型, , "0"
.局部变量 tmp, 整数型
.局部变量 i, 整数型

.如果真 (c ≤ 0)
    返回 (假)
.如果真结束
整数位数 = 求位数 (c, 每一位数字)
' 调试输出 (整数位数, 每一位数字)
.计次循环首 (取数组成员数 (每一位数字), i)
    tmp = tmp + 求次方 (每一位数字 , 整数位数)
.计次循环尾 ()
.如果真 (tmp = c)
    返回 (真)
.如果真结束
返回 (假)
' 1634是四叶玫瑰数
' 8208是四叶玫瑰数
' 9474是四叶玫瑰数
' 153是水仙花数
' 370是水仙花数
' 371是水仙花数
' 407是水仙花数


.子程序 是否为快乐数, 逻辑型
.参数 一个数, 整数型
.局部变量 位数
.局部变量 数字的数组, 整数型, , "0"
.局部变量 i, 整数型
.局部变量 ret, 整数型
.局部变量 循环了吗, 整数型, 静态, "0"
.局部变量 第几次, 整数型, 静态

.如果真 (一个数 = 0)
    .如果 (取数组成员数 (循环了吗) > 0)
      调试输出 (到文本 (循环了吗 ) + “不是快乐数!”)
    .否则
      调试输出 (“不是快乐数!”)
    .如果结束
    重定义数组 (循环了吗, 假, 0)
    第几次 = 0
    返回 (假)
.如果真结束
第几次 = 第几次 + 1
.计次循环首 (取数组成员数 (循环了吗), i)
    .如果真 (循环了吗 = 一个数)
      调试输出 (到文本 (循环了吗 ) + “循环了!!” + “不是快乐数”)
      重定义数组 (循环了吗, 假, 0)
      第几次 = 0
      返回 (假)
    .如果真结束

.计次循环尾 ()
加入成员 (循环了吗, 一个数)
位数 = 求位数 (一个数, 数字的数组)
ret = 0
.计次循环首 (位数, i)
    ret = ret + 求次方 (数字的数组 , 2)
.计次循环尾 ()
' 调试输出 (ret)
.如果真 (ret > 1)
    返回 (是否为快乐数 (ret))
.如果真结束
.如果真 (ret = 1)
    .如果 (取数组成员数 (循环了吗) > 0)
      调试输出 (到文本 (循环了吗 ) + “是快乐数!”)
    .否则
      调试输出 (“是快乐数!”)
    .如果结束
    重定义数组 (循环了吗, 假, 0)
    返回 (真)
.如果真结束
重定义数组 (循环了吗, 假, 0)
第几次 = 0
返回 (假)


.子程序 取因子, 逻辑型
.参数 n, 整数型
.参数 因子数组, 整数型, 参考 数组
.局部变量 i, 整数型

重定义数组 (因子数组, 假, 0)
.计次循环首 (n, i)
    .如果真 (n % i = 0 且 i ≠ n)
      加入成员 (因子数组, i)
    .如果真结束

.计次循环尾 ()
.如果真 (取数组成员数 (因子数组) > 0)
    返回 (真)
.如果真结束
返回 (假)


.子程序 求阶乘, 长整数型
.参数 n, 整数型
.局部变量 i, 整数型
.局部变量 ret, 整数型

.如果真 (n < 0)
    返回 (0)
.如果真结束
.如果真 (n = 0)
    返回 (1)
.如果真结束
ret = 1
.计次循环首 (n, i)
    ret = i × ret
.计次循环尾 ()
返回 (ret)


.子程序 求阶乘_递归, 长整数型
.参数 n, 整数型
.局部变量 i, 整数型
.局部变量 ret, 整数型

.如果真 (n < 0)
    返回 (0)
.如果真结束
.如果真 (n = 0)
    返回 (1)
.如果真结束
返回 (n × 求阶乘_递归 (n - 1))


.子程序 求阶乘和, 长整数型
.参数 n

.如果真 (n < 0)
    返回 (0)
.如果真结束
.如果真 (n ≤ 1)
    返回 (1)
.如果真结束
返回 (求阶乘_递归 (n) + 求阶乘和 (n - 1))



程序集三

.版本 2
.支持库 EDataStructure
.支持库 spec

.程序集 文本操作

.子程序 split算法实现
.参数 待分割文本, 文本型
.参数 用作分割的文本, 文本型
.参数 要返回的子文本数目, 整数型, 可空
.参数 返回的文本数组, 文本型, 数组
.局部变量 总长度, 整数型
.局部变量 分割文本长度, 整数型
.局部变量 上次查找位置, 整数型
.局部变量 本次查找位置, 整数型
.局部变量 ret, 文本型

.如果真 (要返回的子文本数目 = 1)
    加入成员 (返回的文本数组, 待分割文本)
    返回 ()
.如果真结束
总长度 = 取文本长度 (待分割文本)
分割文本长度 = 取文本长度 (用作分割的文本)
重定义数组 (返回的文本数组, 假, 0)
.判断循环首 (本次查找位置 ≠ -1)
    .如果真 (要返回的子文本数目 - 取数组成员数 (返回的文本数组) = 1)
      本次查找位置 = -1
      ret = 取文本中间 (待分割文本, 上次查找位置 + 分割文本长度, 总长度 - 上次查找位置)
      加入成员 (返回的文本数组, ret)
      返回 ()
    .如果真结束
    本次查找位置 = 寻找文本 (待分割文本, 用作分割的文本, 选择 (上次查找位置 = 0, 1, 上次查找位置 + 分割文本长度), 真)
    .如果 (本次查找位置 = -1)
      ret = 取文本中间 (待分割文本, 上次查找位置 + 分割文本长度, 总长度 - 上次查找位置)
    .否则
      ret = 取文本中间 (待分割文本, 选择 (上次查找位置 = 0, 1, 上次查找位置 + 分割文本长度), 选择 (上次查找位置 = 0, 本次查找位置 - 1, 本次查找位置 - 上次查找位置 - 分割文本长度))
    .如果结束

    上次查找位置 = 本次查找位置
    .如果真 (ret ≠ “”)
      加入成员 (返回的文本数组, ret)
    .如果真结束

.判断循环尾 ()


.子程序 是否为有效的括号, 逻辑型
.参数 给定的文本, 文本型
.局部变量 括号对_小括号, 节点
.局部变量 括号对_中括号, 节点
.局部变量 括号对_大括号, 节点
.局部变量 括号对, 节点, , "0"
.局部变量 取出的括号, 文本型
.局部变量 str0, 文本型, , "0"
.局部变量 i, 整数型
.局部变量 strtmp, 文本型
.局部变量 j, 整数型
.局部变量 标记, 整数型
.局部变量 栈, 栈
.局部变量 栈顶节点, 节点

给定的文本 = 子文本替换 (给定的文本, “ ”, “”, , , 真)
.如果真 (给定的文本 = “”)
    返回 (假)' 空文本
.如果真结束
括号对_小括号.加入属性 (“左括号”, “(”)
括号对_小括号.加入属性 (“右括号”, “)”)
括号对_中括号.加入属性 (“左括号”, “[”)
括号对_中括号.加入属性 (“右括号”, “]”)
括号对_大括号.加入属性 (“左括号”, “{”)
括号对_大括号.加入属性 (“右括号”, “}”)
加入成员 (括号对, 括号对_小括号)
加入成员 (括号对, 括号对_中括号)
加入成员 (括号对, 括号对_大括号)

.计次循环首 (取文本长度 (给定的文本), i)
    strtmp = 取文本中间 (给定的文本, i, 1)
    标记 = 0
    .计次循环首 (取数组成员数 (括号对), j)
      .如果 (括号对 .取文本值 (“左括号”, 取出的括号))
            .如果真 (取出的括号 = strtmp)
                栈.压入 (括号对 )
                标记 = 1
                跳出循环 ()
            .如果真结束

      .否则
            调试输出 (“取左括号时异常”)
      .如果结束
      .如果 (括号对 .取文本值 (“右括号”, 取出的括号))
            .如果真 (取出的括号 = strtmp)
                .如果 (栈.取栈顶节点 (栈顶节点))
                  .如果 (栈顶节点.取文本值 (“右括号”, 取出的括号))
                        .如果真 (取出的括号 = strtmp)
                            .如果 (栈.弹出 (栈顶节点))
                              标记 = 1' 完成1对
                              跳出循环 ()
                            .否则
                              调试输出 (取失败原因 (), 2)
                            .如果结束

                        .如果真结束

                  .否则
                        调试输出 (“栈顶节点取右括号异常”)
                  .如果结束

                .否则
                  调试输出 (取失败原因 (), 1)
                .如果结束

            .如果真结束

      .否则
            调试输出 (“取右括号时异常”)
      .如果结束

    .计次循环尾 ()
    .如果真 (标记 = 0)
      调试输出 (“第” + 到文本 (i) + “个字符'” + strtmp + “'异常”)
      返回 (假)
    .如果真结束

.计次循环尾 ()
.如果真 (栈.取大小 () = 0)
    返回 (真)
.如果真结束
返回 (假)


.子程序 题目11_剪刀石头布_数字转文本, 文本型, , 1代表剪刀 2代表石头 3代表布
.参数 参, 整数型

.如果真 (参 = 1)
    返回 (“剪刀”)
.如果真结束
.如果真 (参 = 2)
    返回 (“石头”)
.如果真结束
.如果真 (参 = 3)
    返回 (“布”)
.如果真结束
返回 (“异常”)



程序集四
.版本 2
.支持库 spec

.程序集 其他

.子程序 题目19_深入理解递归函数_简单的递归
.参数 n, 整数型

.如果真 (n = 0)
    返回 ()
.如果真结束
调试输出 (“'递归前->”, n)
题目19_深入理解递归函数_简单的递归 (n - 1)
调试输出 (“递归后->”, n)


.子程序 题目20_斐波那契递归函数_调用, 长整数型
.参数 n, 整数型
.局部变量 斐波那契数列, 长整数型, 静态, "0"

' 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:
' 1、1、2、3、5、8、13、21、34、...
' 这个数列,前两项都是数字1,从第三项开始,每一项数字是前两项数字之和
' 关系表达式【f(n) = f(n-1)+f(n-2)】
.判断循环首 (取数组成员数 (斐波那契数列) < n)
    加入成员 (斐波那契数列, 0)
.判断循环尾 ()
.如果真 (斐波那契数列 > 0)
    返回 (斐波那契数列 )
.如果真结束
.如果真 (n ≤ 2)
    返回 (1)
.如果真结束
斐波那契数列 = 题目20_斐波那契递归函数_调用 (n - 1) + 题目20_斐波那契递归函数_调用 (n - 2)
返回 (斐波那契数列 )




甜萝 发表于 2022-9-17 18:51

本帖最后由 paypojie 于 2022-9-17 18:59 编辑

题目蛮经典 适合新手练手 也可以回顾一下以前的知识:lol
ps: 这个应该发在编程语言区 而不是脱壳破解区

qingjiumojinshu 发表于 2022-9-17 18:59

有用,试试

泥浆灰 发表于 2022-9-17 19:25

很有用,学习了。

dork 发表于 2022-9-17 20:01

牛逼,收藏了

89684828 发表于 2022-9-17 20:04

谢谢楼主,期待更好的作品!

xiaoyi7 发表于 2022-9-17 20:38

收藏了,很适合我

apeopleofchina 发表于 2022-9-17 20:55

学习了,谢谢分享

外酥内嫩 发表于 2022-9-17 21:00

适用于强化基础
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: Python语法的25个练习题