Linux C编程一站式学习笔记6

news2025/1/2 5:11:49

Linux C编程一站式学习笔记 chap6 循环结构

文章目录

  • Linux C编程一站式学习笔记 chap6 循环结构
  • 一.while语句
    • 递归 VS 循环
        • 函数式编程(Functional Programming) & 命令式编程(Imperative Programming)
        • 无限递归 & 无限循环
    • 习题
    • 欧几里得算法可视化
  • 二.do/while语句
  • 三.for语句
  • 四.break和continue语句
    • 习题
  • 五.嵌套循环
    • 练习
  • 六.goto语句和标号
  • 相关资源、参考资料

一.while语句

  • 我们回顾一下用递归求n!的方法,其实每次递归调用都在重复做同样一件事,就是把n乘到(n-1)!上然后把结果返回。虽说是重复,但每次做都稍微有一点区别(n的值不一样),这种每次都有一点区别的重复工作称为迭代(Iteration)。虽然迭代用递归来做就够了,但C语言提供了循环语句使迭代程序写起来更方便。

  • 之前的factorialwhile语句可以写成

    int factorial(int n)
    {
        int result = 1;
        while (n > 0) {
            result = result * n;
            n = n - 1;
        }
        return result;
    }
    
  • while语句由一个控制表达式和一个子语句组成,子语句可以是若干条语句组成的语句块

    语句→while(控制表达式)语句

    • 若控制表达式的值为真,子语句就被执行,然后再次测试控制表达式的值,如果还是真,就把子语句再执行一遍,再测试控制表达式的值…这种控制流程称为循环(Loop),子语句称为循环体
    • 若某次测试控制表达式的值为假,就跳出循环执行后面的return语句
    • 如果第一次测试控制表达式的值就是假,那么直接跳到return语句,循环体一次都不执行
  • 变量result在这个循环中的作用是累加器**(Accumulator),把每次循环的中间结果累积起来,循环结束后得到的累积值就是最终结果,由于这个例子是用乘法来累积的,所以result的初值是1,如果用加法累积则result的初值应该是0。变量n循环变量(Loop Variable)**,每次循环要改变它的值,在控制表达式中要测试它的值,这两点合起来起到控制循环次数的作用,在这个例子中n的值是递减的,也有些循环采用递增的循环变量。这个例子具有一定的典型性,累加器和循环变量这两种模式在循环中都很常见

递归 VS 循环

  • 递归能解决的问题用循环也能解决,但解决思路不同
    • 用递归解决这个问题靠的是递推关系n!=n·(n-1)!
    • 用循环解决这个问题则更像是把这个公式展开了:n!=n·(n-1)·(n-2)·…·3·2·1
  • 把公式展开了理解会更直观一些,所以有些时候循环程序比递归程序更容易理解。但也有一些公式要展开是非常复杂的甚至是不可能的,反倒是递推关系更直观一些,这种情况下递归程序比循环程序更容易理解

函数式编程(Functional Programming) & 命令式编程(Imperative Programming)

  • 之前的factorial递归的例子中,在整个递归调用过程中,虽然分配和释放了很多变量,但所有变量都只在初始化时赋值,没有任何变量的值发生过改变,这种思路称为函数式编程(Functional Programming)
  • 而上面的循环程序则通过对nresult这两个变量多次赋值来达到同样的目的。这种思路称为命令式编程(Imperative Programming)
  • 函数式编程的“函数”类似于数学函数的概念,C语言的函数可以有Side Effect,比如在一个函数中修改某个全局变量的值就是一种Side Effect。全局变量被多次赋值会给调试带来麻烦,如果一个函数体很长,控制流程很复杂,那么局部变量被多次赋值也会有同样的问题。
  • 因此,不要以为“变量可以多次赋值”是天经地义的,有很多编程语言可以完全采用函数式编程的模式,避免Side Effect,例如LISP、Haskell、Erlang等。用C语言编程主要还是采用Imperative的模式,但要记住,给变量多次赋值时要格外小心,在代码中多次读写同一变量应该以一种一致的方式进行。所谓“一致的方式”是说应该有一套统一的规则,规定在一段代码中哪里会对某个变量赋值、哪里会读取它的值。

无限递归 & 无限循环

  • 递归函数如果没写 base case,容易变成无穷递归,循环不注意的话也容易变成无限循环(Infinite Loop)或叫死循环。

  • 例如前面这个例子

    int factorial(int n)
    {
        int result = 1;
        while (n > 0) {
            result = result * n;
            n = n - 1;
        }
        return result;
    }
    
    • 若写成while(1) {...} ,或者漏了n = n - 1,就变成了死循环
  • 但有时候 是否为死循环 不是一目了然的

    while (n != 1) {
    	if (n % 2 == 0) {
    		n = n / 2;
    	} else {
    		n = n * 3 + 1;
    	}
    }
    

    如果n为正整数,这个循环能跳出来吗?这个是著名的3x+1猜想

    能找出不少例子,比如n一开始为7,最后得到1,但无论试多少个数也不能代替证明,这个循环有没有可能对某些正整数n是死循环呢?

习题

1、用循环解决第 3 节 “递归”的所有习题,体会递归和循环这两种不同的思路。

  • 求两个正整数ab的最大公约数(GCD,Greatest Common Divisor),使用Euclid算法

    • 如果a除以b能整除,则最大公约数是b
    • 否则,最大公约数等于ba%b的最大公约数

    这个算是大一学的时候的经典问题了…

    一开始想到的是这个最原始的,但是忘了审题hhh,Euclid算法

    #include <stdio.h>
    #include <math.h>
    
    int GCD(int a, int b)
    {
        int gcd = 1;
        int i;
        for (i = 1; i <= a && i <= b; i++)
        {
            if (a % i == 0 && b % i == 0)
            {
                gcd = i;
            }
        }
        return gcd;
    }
    
    // Driver program to test above function
    int main()
    {
        int a = 98, b = 56;
        printf("GCD of %d and %d is %d ", a, b, GCD(a, b));
        return 0;
    }
    

    记得大一的时候总是不确定控制表达式里面写什么,现在再来看看算法的描述:如果a除以b能整除,则最大公约数是b,否则,最大公约数等于ba%b的最大公约数

    要找到最大公约数,那就是余数为0啊,那么肯定是把余数作为控制条件

    令 r = a % b,则 a = m * b + r

    我们就引入三个变量,但是要迭代表示这个算法,所以注意变量身份的变化

    a 除以 b , b 除以 (a%b)

    也就是 迭代的时候 b 取代了 a的位置, 而 a%b 取代了 b的位置

    所以是 r = a % b, a = b, b = r

    如果a能整除b,那么r一开始就是0,a和b的最大公约数为b,b=r之后b也为0, 于是退出循环,而要return 最大公约数,本该return b,但是b赋值给了a,所以return a

    如果a不能整除b,那么就要经历数次迭代了,在最后一次的时候,r = a(是上一轮的b)% b(是上一轮的a%b) 为0 ,赋值给b,b为0退出循环, 而这一次,最大公约数就是b(上一轮的a%b),但是赋值给了a,所以return a

    #include <stdio.h>
    #include <math.h>
    
    int GCD(int a, int b)
    {
        //using euclid algorithm and for loops
        int r;
        while (b != 0)
        {
            r = a % b;
            a = b;
            b = r;
        }
        return a;
    }
    
    // Driver program to test above function
    int main()
    {
        int a = 98, b = 56;
        printf("GCD of %d and %d is %d ", a, b, GCD(a, b));
        return 0;
    }
    
    image-20230126121649152
  • 求Fibonacci数列的第n项,这个数列是这样定义的

    • fib(0)=1
      fib(1)=1
      fib(n)=fib(n-1)+fib(n-2)

    一开始想到的是这个代码,是正确的,但是感觉写的一般般

    需要注意的是for (i = 2; i <= n; i++)这里的循环次数, 设置成2和n挺好理解的,从第二项要算到第n项

    #include <stdio.h>
    #include <math.h>
    
    int Fibonacci(int n)
    {
        if (n == 0 || n == 1)
        {
            return 1;
        }
    
        else
        {
            int i;
            int f1 = 1;
            int f2 = 1;
            int f3;
            for (i = 2; i <= n; i++)
            {
                f3 = f1 + f2;
                f2 = f1;
                f1 = f3;
            }
            return f3;
        }
    }
    
    int main()
    {
        printf("%d ", Fibonacci(0));
        printf("%d ", Fibonacci(1));
        printf("%d ", Fibonacci(2));
        printf("%d ", Fibonacci(3));
        printf("%d ", Fibonacci(4));
        printf("%d ", Fibonacci(5));
        printf("%d ", Fibonacci(6));
        printf("%d ", Fibonacci(7));
        printf("%d ", Fibonacci(8));
        printf("%d ", Fibonacci(9));
    }
    

2、编写程序数一下1到100的所有整数中出现多少次数字9。在写程序之前先把这些问题考虑清楚:

  1. 这个问题中的循环变量是什么?
  2. 这个问题中的累加器是什么?用加法还是用乘法累积?
  3. 在第 2 节 “if/else语句”的习题1写过取一个整数的个位和十位的表达式,这两个表达式怎样用到程序中?
  • 循环变量就是用一个遍历1~100的变量

  • 累加器就是次数,用加法

  • my code

    #include <stdio.h>
    #include <math.h>
    
    int CountNine()
    {
        int num = 0;
        int i;
        for(i=1; i<=100; i++)
        {
            int s = i % 10; //个位
            int t = i / 10; //十位
            if(s == 9)
                num += 1;
            if(t == 9)
                num += 1;
        }
        return num;
    }
    
    // Driver program to test above function
    int main()
    {
        printf("%d", CountNine());
    }
    

    答案20

    要是把这题改一下,改成出现过9的数字的个数,答案是19,因为99里面重复统计一次,那就得稍微改改了

    #include <stdio.h>
    
    int main()
    {
        int count = 0;
        int i;
    
        for (i = 1; i <= 100; i++)
        {
            if (i % 10 == 9 || i / 10 == 9)
            {
                count++;
            }
        }
        printf("%d", count);
        return 0;
    }
    
    

欧几里得算法可视化

做上面练习的时候,感觉还是不直观,于是去搜谷歌:visualize euclid,果真搜到了!

  • 有大佬在geogebra做了:https://www.geogebra.org/m/vwwezney

二.do/while语句

  • syntax:

    语句 → do 语句 while (控制表达式);

  • while语句先测试控制表达式的值再执行循环体,而do/while语句先执行循环体再测试控制表达式的值。如果控制表达式的值一开始就是假,while语句的循环体一次都不执行,而do/while语句的循环体仍然要执行一次再跳出循环。

三.for语句

  • syntax:

    for (控制表达式1; 控制表达式2; 控制表达式3) 语句

    如果不考虑循环体中包含continue语句的情况,这个for循环等价于下面的while循环:

    控制表达式1;
    while (控制表达式2) {
    	语句
    	控制表达式3;
    }
    

    从这种等价形式来看,控制表达式1和3都可以为空,但控制表达式2是必不可少的,例如for (;1;) {...}等价于while (1) {...}死循环。C语言规定,如果控制表达式2为空,则认为控制表达式2的值为真,因此死循环也可以写成for (;;) {...}

  • ++i,--i ,i++,i--

    • ++称为前缀自增运算符(Prefix Increment Operator),类似地,--称为前缀自减运算符(Prefix Decrement Operator)[10],--i相当于i = i - 1如果把++i这个表达式看作一个函数调用,除了传入一个参数返回一个值(等于参数值加1)之外,还产生一个Side Effect,就是把变量i的值增加了1。

    • i++i--,为了和前缀运算符区别,这两个运算符称为后缀自增运算符(Postfix Increment Operator)后缀自减运算符(Postfix Decrement Operator)如果把i++这个表达式看作一个函数调用,传入一个参数返回一个值,返回值就等于参数值(而不是参数值加1),此外也产生一个Side Effect,就是把变量i的值增加了1,它和++i的区别就在于返回值不同。同理,--i返回减1之后的值,而i--返回减1之前的值,但这两个表达式都产生同样的Side Effect,就是把变量i的值减了1。

    • 使用++、–运算符会使程序更加简洁,但也会影响程序的可读性

  • C99 的一种for循环写法

    C99规定了一种新的for循环语法,在控制表达式1的位置可以有变量定义。例如上例的循环变量i可以只在for循环中定义:

    int factorial(int n)
    {
    	int result = 1;
    	for(int i = 1; i <= n; i++)
    		result = result * i;
    	return result;
    }
    

    如果这样定义,那么变量i只是for循环中的局部变量而不是整个函数的局部变量,相当于语句块中的局部变量,在循环结束后就不能再使用i这个变量了。这个程序用gcc编译要加上选项-std=c99。这种语法也是从C++借鉴的,考虑到兼容性不建议使用这种写法。

四.break和continue语句

  • 前面学switch的时候第一次见到了break,用来跳出switch语句块,这个语句也可以用来跳出循环体。

  • continue语句也会终止当前循环,和break语句不同的是,continue语句终止当前循环后又回到循环体的开头准备执行下一次循环。

    • 对于while循环和do/while循环,执行continue语句之后测试控制表达式,如果值为真则继续执行下一次循环;
    • 对于for循环,执行continue语句之后首先计算控制表达式3,然后测试控制表达式2,如果值为真则继续执行下一次循环。例如下面的代码打印1到100之间的素数:

    例 6.1. 求1-100的素数

    #include <stdio.h>
    
    int is_prime(int n)
    {
    	int i;
    	for (i = 2; i < n; i++)
    		if (n % i == 0)
    			break;
    	if (i == n)
    		return 1;
    	else
    		return 0;
    }
    
    int main(void)
    {
    	int i;
    	for (i = 1; i <= 100; i++) {
    		if (!is_prime(i))
    			continue;
    		printf("%d\n", i);
    	}
    	return 0;
    }
    

    is_prime函数从2到n-1依次检查有没有能被n整除的数,如果有就说明n不是素数,立刻跳出循环而不执行i++。因此,如果n不是素数,则循环结束后i一定小于n,如果n是素数,则循环结束后i一定等于n。注意检查临界条件:2应该是素数,如果n是2,则循环体一次也不执行,但i的初值就是2,也等于n,在程序中也判定为素数。其实没有必要从2一直检查到n-1,只要从2检查到⌊sqrt(n)⌋,如果全都不能整除就足以证明n是素数了,请读者想一想为什么。

    因为对称性:

    Why do we check up to the square root of a number to determine if the number is prime?

    • Sqrt:square root

    在主程序中,从1到100依次检查每个数是不是素数,如果不是素数,并不直接跳出循环,而是i++后继续执行下一次循环,因此用continue语句。注意主程序的局部变量iis_prime中的局部变量i是不同的两个变量,其实在调用is_prime函数时主程序的局部变量i和参数n的值相等。

习题

1、求素数这个程序只是为了说明breakcontinue的用法才这么写的,其实完全可以不用breakcontinue,请读者修改一下控制流程,去掉breakcontinue而保持功能不变。

  • my solution

    #include <stdio.h>
    
    int is_prime(int n)
    {
        int i;
        int flag = 1; //1表示是素数
        for (i = 2; i < n; i++)
        {
            if(n%i == 0)
            {
                flag = 0; //0表示不是素数
            }
        }
        return flag;
    }
    
    int main(void)
    {
        int i;
        for (i = 2; i <= 100; i++)
        {
            if (is_prime(i))
                printf("%d\n", i);
        }
        return 0;
    }
    

其实可以再简化,不需要flag,要记得return这个东西,比break还terminate得更彻底

#include <stdio.h>

int is_prime(int n)
{
    int i;
    for (i = 2; i < n; i++)
    {
        if(n%i == 0)
        {
            return 0;
        }
    }
    return 1;
}

int main(void)
{
    int i;
    for (i = 2; i <= 100; i++)
    {
        if (is_prime(i))
            printf("%d\n", i);
    }
    return 0;
}

2、上一节讲过怎样把for循环改写成等价的while循环,但也提到如果循环体中有continue语句这两种形式就不等价了,想一想为什么不等价了?

for (控制表达式1; 控制表达式2; 控制表达式3) 语句

continue执行完后 会执行for循环中的 控制表达式3

控制表达式1;
while (控制表达式2) {
	语句
	控制表达式3;
}

而while中遇到continue 会跳过控制表达式3


不过我寻思…while循环里,把continue写在控制表达式3的后面不就又等价了吗😝

五.嵌套循环

  • 上一节求素数的例子中,在一个循环中调用is_prime函数,而那个函数里面又有个循环,其实这就是嵌套循环,如果全写在main函数里面就是这样👇

    #include <stdio.h>
    
    int main(void)
    {
    	int i, j;
    	for (i = 1; i <= 100; i++) {
    		for (j = 2; j < i; j++)
    			if (i % j == 0)
    				break;
    		if (j == i)
    			printf("%d\n", i);
    	}
    	return 0;
    }
    

练习

  • 打印乘法口诀表

    1	
    2	4	
    3	6	9	
    4	8	12	16	
    5	10	15	20	25	
    6	12	18	24	30	36	
    7	14	21	28	35	42	49	
    8	16	24	32	40	48	56	64	
    9	18	27	36	45	54	63	72	81
    
    • my code

      #include <stdio.h>
      
      void PrintProduct()
      {
          int i, j;
          for ( i = 1; i <= 9; i++)
          {
              for (j= 1; j <= i; j++)
              {
                  printf("%d ", i * j);
              }
              printf("\n");
          }
      }
      
      int main(void)
      {
          PrintProduct();
      }
      
  • 编写函数diamond打印一个菱形。如果调用diamond(3, '*')则打印:

    	*
    *	*	*
    	*
    

    如果调用diamond(5, '+')则打印:

    		+
    	+	+	+
    +	+	+	+	+
    	+	+	+
    		+
    

    如果用偶数做参数则打印错误提示。

    • my code

      #include <stdio.h>
      
      /*
      编写函数diamond打印一个菱形。如果调用diamond(3, '*')则打印:
      
          *
      *	*	*
          *
      如果调用diamond(5, '+')则打印:
      
              +
          +	+	+
      +	+	+	+	+
          +	+	+
              +
      如果用偶数做参数则打印错误提示。
      using C language
      */
      
      // 用于打印菱形
      void diamond(int n, char c)
      {
          int i, j, k;
          if (n % 2 == 0)
          {
              printf("Error: n must be odd number");
              return;
          }
          for (i = 0; i < n; i++)
          {
              if (i < n / 2)
              {
                  for (j = 0; j < n / 2 - i; j++)
                      printf("  ");
                  for (k = 0; k < 2 * i + 1; k++)
                      printf("%c ", c);
              }
              else
              {
                  for (j = 0; j < i - n / 2; j++)
                      printf("  ");
                  for (k = 0; k < 2 * (n - i) - 1; k++)
                      printf("%c ", c);
              }
              printf("\n");
          }
      }
      // 主函数
      int main()
      {
          int n;
          char c;
          // printf("Please input n and c:");
          // scanf("%d %c", &n, &c);
          // diamond(n, c);
          diamond(5, '+');
          return 0;
      }
      

六.goto语句和标号

  • goto语句,能实现无条件跳转。我们知道break只能跳出最内层的循环,如果在一个嵌套循环中遇到某个错误条件需要立即跳出最外层循环做出错处理,就可以用goto语句,例如:

    for (...)
    	for (...) {
    		...
    		if (出现错误条件)
    			goto error;
    	}
    error:
    	出错处理;
    

    这里的error:叫做标号(Label),任何语句前面都可以加若干个标号,每个标号的命名也要遵循标识符的命名规则。

  • goto语句唯一的限制是goto只能跳转到同一个函数中的某个标号处,而不能跳到别的函数中

    C标准库函数setjmplongjmp配合起来可以实现函数间的跳转,但只能从被调用的函数跳回到它的直接或间接调用者(同时从栈空间弹出一个或多个栈帧),而不能从一个函数跳转到另一个和它毫不相干的函数中。setjmp/longjmp函数主要也是用于出错处理,比如函数A调用函数B,函数B调用函数C,如果在C中出现某个错误条件,使得函数BC继续执行下去都没有意义了,可以利用setjmp/longjmp机制快速返回到函数A做出错处理

  • goto语句不是必须存在的,显然可以用别的办法替代,比如上面的代码段可以改写为

    
    int cond = 0; /* bool variable indicating error condition */
    for (...) {
    	for (...) {
    		...
    		if (出现错误条件) {
    			cond = 1;
    			break;
    		}
    	}
    	if (cond)
    		break;
    }
    if (cond)
    	出错处理;
    
  • 滥用 goto语句会使程序的控制流程非常复杂,可读性很差


从这个角度来讲case和default我没有想到,orz

  • 事实上case 常量表达式:default:,它们是两种特殊的标号。和标号有关的语法规则如下:

    语句 → 标识符: 语句
    语句 → case 常量表达式: 语句
    语句 → default: 语句
    

    反复应用这些语法规则进行组合可以在一条语句前面添加多个标号,比如之前学的这个

    orz,现在从语法规则的角度来看,更加能理解这种了

    img

相关资源、参考资料

  • 豆瓣评价

  • 开源电子书

  • 《Linux C编程一站式学习》这书写得很不错,为什么都买不到了呢? - echo1937的回答 - 知乎 https://www.zhihu.com/question/34069391/answer/544825938

  • [大佬们的学习笔记]

    • 习题答案整理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/179919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光流估计(二) FlowNet 系列文章解读

在上篇文章中&#xff0c;我们学习并解了光流&#xff08;Optical Flow&#xff09;的一些基本概念和基本操作&#xff0c;但是传统的光流估计方法计算比较复杂、成本较高。近些年来随着CNN卷积神经网络的不断发展和成熟&#xff0c;其在各种计算机视觉任务中取得了巨大成功&am…

docker-基础实战第六课镜像挂载

镜像挂载: docker run --namemynginx -d --restartalways -p 8088:80 -v /usr/local/docker/data/html:/usr/share/nginx/html:ro nginx访问403 原因: /usr/local/docker/data/html 没有创建index.html 需要创建目录并且创建index.html docker命令补充&#xff1a; 如果有一…

向QAbstractItemView子类如:QTreeView、QTableView等子项单元格插入窗体小部件的功能实现(第1种方法)

1.前言 工作中经常会遇到这样的需求&#xff1a;向QAbstractItemView子类如QTreeView、QTableView单元格插入窗体小部件&#xff0c;如&#xff1a;进度条、按钮、单行编辑框等。下面链接的系列博文就是讲解如何实现该功能的。《向QAbstractItemView子类如:QTreeView、QTableVi…

Android音频播放有杂音?原来是这个JAVA API接口惹的祸

最近在调试一个基于十年前Android版本的多媒体应用软件时&#xff0c;遇到了音频播放的问题&#xff0c;这里记录问题的发现、分析和处理过程。 有人可能会好奇&#xff0c;十年前的Android版本是什么版本&#xff1f;大家可以去Google网站上查查&#xff0c;就是目前Android网…

Android深入系统完全讲解(40)

调试 C 代码 15.1 改成 C 写法 这个没啥必要&#xff0c;但是对 C 比 C 情谊深的我&#xff0c;把它修改了。下面是修改的一部分代码&#xff0c; 把 C 的写法&#xff0c;改成 C 的&#xff0c;同时修改引入头文件。 jstring Java_hellojni_codegg_com_hellojni_MainActivity_…

Java基础41 面向对象(高级)

面向对象&#xff08;高级&#xff09;一、类变量和类方法1.1、static &#xff08;类变量&#xff09;1.1.1 关于static的存放位置1.1.2 类变量使用细节及注意事项1.2、类方法1.2.1、类方法使用细节及注意事项二、main方法2.1、深入理解main方法三、代码块3.1、代码块的基本介…

19.6、Javaweb_案例旅游路线收藏功能

旅游线路收藏功能 分析 判断当前登录用户是否收藏过该线路 当页面加载完成后&#xff0c;发送ajax请求&#xff0c;获取用户是否收藏的标记 根据标记&#xff0c;展示不同的按钮样式 编写代码 后台代码 RouteServlet&#xff1a; package cn.itcast.travel.web.servlet;…

【Typescript学习】使用 React 和 TypeScript 构建web应用(四)useReducer、扑街了的分区功能【完结了】

教程来自freecodeCamp&#xff1a;【英字】使用 React 和 TypeScript 构建应用程序 跟做&#xff0c;仅记录用 其他资料&#xff1a;https://www.freecodecamp.org/chinese/news/learn-typescript-beginners-guide/ 作者提供的源码https://github.com/piyush-eon/react-typescr…

机器学习【西瓜书/南瓜书】--- 第四章决策树

一、决策树理论分析 1.1 通俗理解 决策树是一种非常经典的机器学习算法&#xff0c;通俗理解的话我们可以举一个例子&#xff0c;比如现在别人要找你借钱&#xff0c;那么按照首先是不是要判断你和他的关系如何?如果关系不好&#xff0c;我就直接拒绝他。如果关系很好&#…

Python机器学习:一元回归

→\rightarrow→回归效果评价 &#x1f315; 一元回归 一元回归主要研究一个自变量和一个因变量之间的关系&#xff0c;而这个自变量和因变量之间的关系又可分为线性回归和非线性回归。 ⭐️ 一元线性回归分析两个变量之间的线性关系&#xff0c;如ykxbykxbykxb中xxx和yyy就是…

深度学习笔记:神经网络的学习(1)

机器学习的核心在于从数据中提取规律和特征&#xff0c;并用于分类或预测。对于识别手写数字&#xff0c;如果人工设计一个识别算法逻辑是十分困难的。一种方法是任务在数据中提取更重要的特征量&#xff0c;然后利用机器学习算法如SVM或KNN。而神经网络的方法则是完全由机器自…

ISIS的3级别(level-1、level-2、level-1-2)4大类(IIH、LSP、CSNP、PSNP)9小类与邻接关系建立LSP交互过程介绍

2.2.0 ISIS 4种报文类型IIH、LSP、CSNP、PSNP、邻居建立过程、交互LSP过程 ISIS的3级别4大类9小类 ISIS拥有3种级别的路由器&#xff0c;分别是level-1、level-2、level-1-2。 不同级别之间进行交互的报文也是有所区别的&#xff0c;常规的ISIS报文分有4大类&#xff1a;IIH、…

cubeIDE开发, stm32人工智能开发应用实践(Cube.AI).篇一

一、cube.AI简介及cubeIDE集成 1.1 cube.AI介绍 cube.AI准确来说是STM32Cube.AI&#xff0c;它是ST公司的打造的STM32Cube生态体系的扩展包X-CUBE-AI&#xff0c;专用于帮助开发者实现人工智能开发。确切地说&#xff0c;是将基于各种人工智能开发框架训练出来的算法模型&#…

Vue3商店后台管理系统设计文稿篇(六)

记录使用vscode构建Vue3商店后台管理系统&#xff0c;这是第六篇&#xff0c;从这一篇章开始&#xff0c;所有的预备工作结束&#xff0c;正式进入商店后台管理系统的开发 文章目录一、创建后台管理系统的标题栏二、安装Icon 图标三、创建Menu菜单正文内容&#xff1a; 一、创…

PowerShell 学习笔记:操作JSON文件

JSON文件&#xff08;字符串&#xff09;是有一定格式要求的文本文件。百度百科JSON&#xff08;JavaScriptObject Notation, JS对象简谱&#xff09;是一种轻量级的数据交换格式。它基于 ECMAScript&#xff08;European Computer Manufacturers Association, 欧洲计算机协会制…

初识Linux常见指令汇总

文章目录前言1.对文件或目录的常用指令1.查看当前路径下的文件或目录相关信息2.进入指定路径3.创建删除文件或者目录4.使用nano简单编辑文件查看文件属性5.复制移动重命名文件或目录6.输入输出重定(查看文件内容)向和搜索查找1.输入输出重定向2.搜索查找7.打包压缩文件2.时间相…

如何使用Maven构建Java项目?Maven的使用详细解读

文章目录1. 前言2. Maven 快速入门2.1 Maven 项目模型2.2 Maven 仓库3. Maven的安装配置3.1 安装3.2 配置环境变量3.4 Maven 配置4. Maven 的常用命令4.1 编译4.2 清理4.3 打包4.4 测试4.5 安装5. Maven生命周期6. 总结Java编程基础教程系列&#xff1a;1. 前言 在 Java 开发中…

C++初阶:list类

文章目录1 list介绍2 list的模拟实现2.1 类的定义2.2 默认成员函数2.2.1 构造函数2.2.2 析构函数2.2.3 拷贝构造2.2.4 赋值重载2.3 迭代器2.3.1 正向迭代器2.3.2 反向迭代器2.4 修改接口2.4.1 任意位置插入2.4.2 任意位置删除2.5 其他接口2.5.1 尾插2.5.2 头插2.5.3 尾删2.5.3 …

3.7-2动态规划--图像压缩(举例子和写代码)

3.7动态规划--图像压缩_昵称什么的不存在的博客-CSDN博客 问题描述&#xff08;再写一遍&#xff09; 这篇文章是接着上面这一篇写的&#xff0c;就是写一个例子方便理解&#xff0c;模拟填写数组的过程 l: l[i]存放第i段长度, 表中各项均为8位长&#xff0c;限制了相同位数的…

CGAL 点云精配准之ICP算法

文章目录 一、简介二、相关参数三、实现过程三、举个栗子四、实现效果参考资料一、简介 ICP算法总共分为6个阶段,如下图所示: (1)挑选发生重叠的点云子集,这一步如果原始点云数据量比较巨大,一般会对原始点云进行下采样操作。 (2)匹配特征点。通常是距离最近的两个点,…