线性表练习之Example013-只用一个变量来求个位数字组成的正整数数组中的最小值

Posted 二木成林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表练习之Example013-只用一个变量来求个位数字组成的正整数数组中的最小值相关的知识,希望对你有一定的参考价值。

Example013

原文链接:Example013

题目

N 个个位正整数存放在 int 型数组 A[0, …, N-1] 中,N 为已定义的常量且 N≤9,数组 A[] 的长度为 N,另给一个 int 型变量 i,要求只用上述变量(A[0]~A[N-1]i,这 N+1 个整型变量〉写一个算法,找出这 N 个整数中的最小者,并且要求不能破坏数组 A[] 中的数据。

分析

对于普通的寻找数组最小值的方法如下,在方法中会用到两个变量 mini。其中 min 用来记录数组中的最小值,而 i 用来作为循环变量控制循环。

    /**
 * 寻找数组 A 中的最小数
 *
 * @param A 由 N 个个位正整数组成的整型数组
 * @return 得到数组中整数的最小数
 */
public int min(int[]A)
        // 初始时,将数组第一个元素置为最小值
        int min=A[0];
        // 循环数组所有元素
        for(int i=0;i<N; i++)
        // 如果发现数组中有元素比最小值还小
        if(A[i]<min)
        // 那么更新记录最小值的变量,将该数记为最小值
        min=A[i];
        
        
        // 返回最小值
        return min;
        

但现在要求只用一个变量 i,也就是说必须用变量 i 来保存最小值和循环变量控制循环。

从题目中得知数组中元素个数最多为 9 个,并且数组中每个数都是个位数,这就给了我们操作的空间。

我们可以用一个十位数 num([10,99])来完成操作,其中让十位数记录最小值 [1, 9],而个位数记录循环变量 [0, 9]

我们可以利用 num/10 得到十位上的数值,而利用 num%10 得到个位上的数,每次 num%10+1 就可以让循环变量加 1 控制循环。

图解

略。

C实现

核心代码:

/**
 * 求数组中的最小值
 * @param A 指定数组
 * @return 最小值
 */
int min(int A[]) 
    // 十位记录最小值,个位记录循环变量
    int i = A[0] * 10 + 0;// 其中 0 就表示循环变量,而A[0]表示临时最小值,乘以 10 是因为它表示十位
    // 其中 i%10 就得到个位数,即循环变量
    while (i % 10 < N) 
        // i/10 可以得到十位数,即记录的最小值,通过 A[i%10] 就相当于 A[0]、A[1] 访问数组中对应下标的值,然后比较大小
        if (i / 10 > A[i % 10]) 
            // 如果该数比记录的最小值还要小,那么就更新变量 i,更新 i 的十位为新的最小值,并且也要更新循环变量,继续数组中的下一个元素
            // A[i%10]就是新的十位,而乘以 10 是让它成为一个两位数,i%10 是获取原来的个位数
            i = A[i % 10] * 10 + i % 10;
        
        // 加 1 就是让个位数加1,就是新的循环变量,等价于原来的 i++
        i += 1;
    
    // 返回最小值,要除以 10 才能得到十位数表示的最小值
    return i / 10;

完整代码:

#include <stdio.h>

#define N 8

/**
 * 求数组中的最小值
 * @param A 指定数组
 * @return 最小值
 */
int min(int A[]) 
    // 十位记录最小值,个位记录循环变量
    int i = A[0] * 10 + 0;// 其中 0 就表示循环变量,而A[0]表示临时最小值,乘以 10 是因为它表示十位
    // 其中 i%10 就得到个位数,即循环变量
    while (i % 10 < N) 
        // i/10 可以得到十位数,即记录的最小值,通过 A[i%10] 就相当于 A[0]、A[1] 访问数组中对应下标的值,然后比较大小
        if (i / 10 > A[i % 10]) 
            // 如果该数比记录的最小值还要小,那么就更新变量 i,更新 i 的十位为新的最小值,并且也要更新循环变量,继续数组中的下一个元素
            // A[i%10]就是新的十位,而乘以 10 是让它成为一个两位数,i%10 是获取原来的个位数
            i = A[i % 10] * 10 + i % 10;
        
        // 加 1 就是让个位数加1,就是新的循环变量,等价于原来的 i++
        i += 1;
    
    // 返回最小值,要除以 10 才能得到十位数表示的最小值
    return i / 10;


int main() 
    int A[] = 2, 4, 6, 1, 5, 3, 7, 8;

    // 调用函数
    int m = min(A);
    printf("最小值:%d", m);

执行结果:

最小值:1

事实上,书上的写法是利用 i 的十位上的数字作为循环变量,将 i 的个位上的数字来代替题目中的 min 的功能,而利用 i%10 取得 i 个位上的数字,i/10 取得 i 十位上的数字。代码如下:

void min(int A[], int &i) // 用 i 来保存最小值
	i=A[0];// i先保存存入A[0]的值
	while(i/10<=N-1)  // 取 i 的十位上的数字作为循环变量,与 N-1 作比较
		if(i%10>A[i/10])  // 取 i 的个位上的数字与 A[i/10] 中的各数值比较
			i=i-i%10;// 如果 i 的个位上的数字大于 A[I/10] 中数字
			i=i+A[i/10];// 则将 i 的个位上的数字换成 A[I/10]
		
		i=i+10;// i 的十位上的数字加 1,即对 A[] 中的下一个数字进行检测
	
	i=i%10;// 循环结束后,i 的个位上的数字保存了 A[] 中的最小值,将 i 更新为 i 的个位上的数字

Java实现

核心代码:

    /**
 * 求数组 A 中的最小值
 *
 * @param A 全是个位正整数的数组
 * @return 数组中的最小值
 */
public int min(int[]A)
        // 十位记录最小值,个位记录循环变量
        int i=A[0]*10+0;// 其中 0 就表示循环变量,而A[0]表示临时最小值,乘以 10 是因为它表示十位
        // 其中 i%10 就得到个位数,即循环变量
        while((i%10)<N)
        // i/10 可以得到十位数,即记录的最小值,通过 A[i%10] 就相当于 A[0]、A[1] 访问数组中对应下标的值,然后比较大小
        if((i/10)>A[i%10])
        // 如果该数比记录的最小值还要小,那么就更新变量 i,更新 i 的十位为新的最小值,并且也要更新循环变量,继续数组中的下一个元素
        // A[i%10]就是新的十位,而乘以 10 是让它成为一个两位数,i%10 是获取原来的个位数
        i=A[i%10]*10+(i%10);
        
        // 加 1 就是让个位数加1,就是新的循环变量,等价于原来的 i++
        i+=1;
        
        // 返回最小值,要除以 10 才能得到十位数表示的最小值
        return i/10;
        

完整代码:

public class SeqList 
    private final int N = 8;

    /**
     * 求数组 A 中的最小值
     *
     * @param A 全是个位正整数的数组
     * @return 数组中的最小值
     */
    public int min(int[] A) 
        // 十位记录最小值,个位记录循环变量
        int i = A[0] * 10 + 0;// 其中 0 就表示循环变量,而A[0]表示临时最小值,乘以 10 是因为它表示十位
        // 其中 i%10 就得到个位数,即循环变量
        while ((i % 10) < N) 
            // i/10 可以得到十位数,即记录的最小值,通过 A[i%10] 就相当于 A[0]、A[1] 访问数组中对应下标的值,然后比较大小
            if ((i / 10) > A[i % 10]) 
                // 如果该数比记录的最小值还要小,那么就更新变量 i,更新 i 的十位为新的最小值,并且也要更新循环变量,继续数组中的下一个元素
                // A[i%10]就是新的十位,而乘以 10 是让它成为一个两位数,i%10 是获取原来的个位数
                i = A[i % 10] * 10 + (i % 10);
            
            // 加 1 就是让个位数加1,就是新的循环变量,等价于原来的 i++
            i += 1;
        
        // 返回最小值,要除以 10 才能得到十位数表示的最小值
        return i / 10;
    

测试代码:

public class SeqListTest 
    public static void main(String[] args) 
        SeqList list = new SeqList();
        int[] A = new int[]2, 4, 3, 5, 7, 1, 6, 8;

        int min = list.min(A);
        System.out.println("最小值:" + min);
    

执行结果:

最小值:1

以上是关于线性表练习之Example013-只用一个变量来求个位数字组成的正整数数组中的最小值的主要内容,如果未能解决你的问题,请参考以下文章

线性表练习之Example004-将顺序表中所有元素逆置

线性表练习之Example021-删除顺序表中的最后一个元素

线性表练习之Example012-逆序打印单链表

线性表练习之Example003-删除单链表最小值节点

线性表练习之Example020-将一个单链表拆分成两个链表,一个顺序一个倒序

线性表练习之Example001-创建不重复字母字符的单链表