左神算法笔记(异或)+C语言实现

简介: 异或性质运算性质应用举例1、不用额外变量,交换两个数的值原理代码2、找到数组中唯一一个出现奇数次的数字3、提取最右侧的1(常用)应用1:找到数组中唯二出现的两个出现奇数次的数字代码应用2:找到二进制有多少1代码

性质


1、相同为0,不同为1

记为不进位相加


运算性质


2、异或运算的性质:A^0=A A^A=0

满足交换律、结合律(多个^顺序不影响答案)


应用举例


1、不用额外变量,交换两个数的值


a=a^b
b=a^b
a=a^b


原理


  int a=甲,int b=乙
    a = 甲^乙
    b = 甲^乙^乙
    a = 甲^乙^乙^甲^乙
  (前提:a,b地址不同)


代码


#include <stdio.h>
int change(int a,int b) {
  a = a ^ b;
  b = a ^ b;
  a = a ^ b;
  printf("a=%d\nb=%d",a,b);
  return 0;
}


2、找到数组中唯一一个出现奇数次的数字


全部异或起来即可


3、提取最右侧的1(常用)


A&(~A)+1


应用1:找到数组中唯二出现的两个出现奇数次的数字


先找到数组全部异或起来以后结果最右侧的1出现在哪一位x


根据第x位是1或0将数组分成两组,分别全部异或,即得结果。


代码


#include <stdio.h>
#include <stdlib.h>
int two_oddTimes_numb(int list[], int size) {
  int i, j ,rightone;
  int eor = 0;
  for (i = 0; i < size; i++) {
    eor ^= list[i];
  }
  rightone = eor & (~eor) + 1;
  //用&实现分组^
  int ans = 0;
  for (j = 0; j < size;j++) {
    if ((list[j] & rightone) != 0) {
      ans ^= list[j];
      printf("%d\n",list[j]);
    }
  }
  char string1[33],string2[33],string3[33];
  _itoa_s(eor, string1, 33, 2);
  _itoa_s(ans, string2, 33, 2);
  _itoa_s(ans^eor, string3, 33, 2);
  printf("库函数得到的二进制为:%s\r\n", string1);
  printf("库函数得到的二进制为:%s\r\n", string2);
  printf("库函数得到的二进制为:%s\r\n", string3);
  printf("两个出现奇数次的数为:%d和%d\n",ans,ans^eor);
  return 0;
}


刚学C,一开始没有初始化eor,以为是默认的0,结果编译可以通过,编译器也没给我提示必须必须初始化。就是结果不对,懵了很久。

结果原因就是C没有默认是0的说法,只声明一个变量只会给他一块地址,里面还有之前系统放的垃圾数据(操作系统回收内存空间时,并不清空该内存空间中遗留下来的数据)

编译器如果发现一个变量里面存放的是一个垃圾值,就认为没有给它赋初值,那么系统就会自动将一个很小的,如 –858993460 这个填充数字给放进去。所以我们看到的结果都是一个不变的值。

还有就是直接printf未初始化的数据会报错,使用这个未初始化的数进行一番操作以后再printf又不会报错了。

我用的visual studio 2022版的,转二进制的时候报itoa()不能用了,要用_itoa_s(int 要转换的数字,char 存放转换结果的字符串,size_t 存放结果的字符数组长度,int 转化的进制数,2表示2进制,10表示10进制),比原来多了一个字段,size_t 类型表示C中任何对象所能达到的最大长度,它是无符号整数。


应用2:找到二进制有多少1


只要还不是1,就一直和自己提取的右边第一个1^,同时计数。


代码


#include <stdio.h>
#include <stdlib.h>
int find_1Times(int a) {
  char str[33];
  _itoa_s(a, str, 33, 2);
  printf("二进制为:%s\n", str);
  int times = 0,tmp =0;
  while (a != 0) {
    //去掉最后一个1
    tmp = a & ((~a) + 1);
    times++;
    a ^= tmp;
  }
  printf("有%d个1\n", times);
}


相关文章
|
2月前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
3月前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
77 1
|
3月前
|
存储 缓存 算法
C语言在实现高效算法方面的特点与优势,包括高效性、灵活性、可移植性和底层访问能力
本文探讨了C语言在实现高效算法方面的特点与优势,包括高效性、灵活性、可移植性和底层访问能力。文章还分析了数据结构的选择与优化、算法设计的优化策略、内存管理和代码优化技巧,并通过实际案例展示了C语言在排序和图遍历算法中的高效实现。
74 2
|
3月前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
91 1
|
3月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
99 1
|
3月前
|
搜索推荐 C语言
【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
本文介绍了快速排序的升级版——三路快排。传统快速排序在处理大量相同元素时效率较低,而三路快排通过将数组分为三部分(小于、等于、大于基准值)来优化这一问题。文章详细讲解了三路快排的实现步骤,并提供了完整的代码示例。
81 4
|
3月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
193 7
|
3月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
156 8
|
3月前
|
存储 算法 数据管理
C语言算法复杂度
【10月更文挑战第20天】
C语言算法复杂度
|
4月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
110 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)

热门文章

最新文章