数据结构与算法实践系列文章(二)数组与字符串
2021/5/19 14:25:44
本文主要是介绍数据结构与算法实践系列文章(二)数组与字符串,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
数组与字符串
数组:
数组的定义:
就是线性表的实现。
c语言
定义: int array[N] 或者 int *array = malloc();
数组的名不是指针。
#include <stdio.h> #include <stdio.h> // 这个地方其实是传入的数组的地址 *array,和大小 int func(int *array,int size){ // array[0] 其实就是指针 array求值得出首地址 return array[0]; // 等价于 *(array+0); } int main(int argc,const char * argv[]){ // array是一个数组 int array[100] = {11,22,33,44}; // 指针的形式 int *p = malloc(100 * sizeof(int)); // 在这里是获取到了数组的指针 printf("%d\n",*(array+1)); // 传入的其实是数组首地址的指针 printf("%d\n",func(array,100)); return 0; }
c++:
数组定义:int array[N] 或 int * array = new int[N];
java
数组定义:int array[] = new int[N];
public class main{ public static void main(String[] args){ int [] array = new int[10]; array[1]=222; array[2]=333; System.out.println(array.length); ArrayList<Integer> list = new ArrayList<>(); list.add(123); list.add(22); System.out.println(list); } }
python
数组定义: array = [];
数组元素的查找:
c语言实现:
#include <stdio.h> /** ** 根据值找到下标 */ int findX(int * array,int size,int x){ int flag=0; int index=-1; for(int i=0;i<size;i++){ if(array[i]==x){ flag =1; index = i; } } return index; } /** ** 根据下标找到值,并把原来的地址给返回过来,并返回状态。 */ int findElement(int * array,int size, int k, int *px){ if(k>=size || k<0) return 0; else{ *px=array[k]; return 1; } } /** * 查找最大的。 */ int findMax(int * array, int size){ // 是将数组中的一个元素初始为max; int max =array[0]; for(int i=1;i<size;i++){ if(max<array[i]) max = array[i]; } return max; } int main(int argc,const char * argv[]){ int array[10] = {111,112,33,44,55}; int x; x=12; int k; k= findX(array,10,x); printf("%d\n",k); int m,flag; // 传入的是数组引用,长度,和下标,和地址 flag= findElement(array,10,3,&m); printf("%d,%d\n",flag,m); // 查找最大值 int max ; max = findMax(array,10); printf("%d\n",max); return 0; }
求两个100位的十进制的和。
C语言实现
int main(int argc, const char * argv[]){ // // 思路 用数组 ,数组的底位存0号元素(如果0号元素存在高位,则是不可以进位的) int a[11] = {0,9,8,7,6,5,4,3,2,1}; int b[11] = {1,2,3,4,5,6,7,8,9,9}; int sum[11] = {0}; int carry=0;//进位操作 // i< 11是为了计算最后一个 for(int i=0;i<11;i++){ int s; s=a[i]+b[i]+carry; carry = s/10; sum[i] = s%10; } for(int i=10;i>=0;i--){ printf("%d",sum[i]); } putchar('\n'); return 0; }
java 实现:
public static void main(String[] args){ BigInteger a= new BigInteger("12345678"); BigInteger b= new BigInteger("12345678"); BigInteger c= a.add(b); System.out.println(c); }
二维数组
二维数组的实质:数组的数组。数组中的每一个元素仍然是个数组。
逻辑上可看做二维,其实并不是二维的
c语言
int array [][] 与 int **array
int array[3][4];和int **pa 的中的array和pa类型是相同的,但是 pa== array的写法是错误的
int array [ ][ ]
与int * *
array是数组的数组。
int *p ===> 是p 指向一个整形变量。
p[2] <==> *(p+2) 就是 p指向的整形变量再+2的位置就是 p[2]
int * * p 因为*靠p元素最近,所以p是一个指针。所以 * * p是指的是指针的指针。p[1][1]
与 p[0][1]
的位置截然不同,并不是相差一个
int * *p= array是错误的
#include <stdio.h> int main(void) { printf("test"); int array[3][5]; // 是由int[5] //int *p[5]; //p =array; // 这样是错误的。 int (*p)[5]; p = array; // 数组名赋值与指针。 那也就是 array是 一个指针。 int a[10]; int *pa =a // s数组的名求值可获取数组元素的受地址。所以 *pa就是一个指针。 return 0; }
数组传参:
#include <stdio.h> vaid func(int (*)[5] , int ){ // int (*)[5] 就是一个指向[5]的指针 } void func(int array[][5] ,int k){ // int array[][5]==>int (*p) [5]; } int main(void) { printf("test"); int array[3][5]; // 是由int[5] //int *p[5]; //p =array; // 这样是错误的。 int (*p)[5]; p = array; // 数组名赋值与指针。 那也就是 array是 一个指针。 // 这传递的是指针 func(array, 3); int a[10]; int *pa =a // s数组的名求值可获取数组元素的受地址。所以 *pa就是一个指针。 return 0; }
java
public void test(){ // 这是个3行的但是列未定义。 int[][] array= new int[3][]; array[0] = new int[5]; // 第0行有5列 ,创建有5个整形变量的数组 arry[1] = new int[4]; array[2]= new int[3]; }
大炮打蚊子案例:
/** * 蚊子分布在一个M×N格的二维平面上,每只蚊子占据一格。向该平面的任意位置发射炮弹,炮弹的杀伤范围如下示意: O OXO O 其中,X为炮弹落点中心,O为紧靠中心的四个有杀伤力的格子范围。若蚊子被炮弹命中(位于X格),一击毙命,若仅被杀伤(位于O格),则损失一半的生命力。也就是说,一次命中或者两次杀伤均可消灭蚊子。现在给出蚊子的分布情况以及连续k发炮弹的落点,给出每炮消灭的蚊子数。 输入格式: 第一行为两个不超过20的正整数M和N,中间空一格,表示二维平面有M行、N列。 接下来M行,每行有N个0或者#字符,其中#表示所在格子有蚊子。 接下来一行,包含一个不超过400的正整数k,表示发射炮弹的数量。 最后k行,每行包括一发炮弹的整数坐标x和y(0≤x<M,0≤y<N),之间用一个空格间隔。 输出格式: 对应输入的k发炮弹,输出共有k行,第i行即第i发炮弹消灭的蚊子数。 输入样例: 5 6 00#00# 000### 00#000 000000 00#000 2 1 2 1 4 输出样例: 0 2 * */ #include <stdio.h> int board[20][20]; int M,N; // 函数处理逻辑 当前坐标 和 杀上力 int bang(int x, int y, int kill){ if((x>=0 && x<M) && (y>=0 && y<N) && board[x][y]>0){ board[x][y] -=kill; if(board[x][y]<=0){ // 蚊子死了 return 1; }else{ return 0; } }else{ return 0; } return 1; } int main(int argc, const char * argv[]){ scanf("%d%d",&M,&N); getchar();// 去除换行符 for(int i=0;i<M;i++){ for(int j=0;j<N;j++){ // 给数组赋值:令蚊子的生命力为2;因为如果为1时炮弹没有击中,而是在 // 炮弹范围内所以让其生命力为2更好计算。 board[i][j] = getchar() == '0' ? 0:2; } // 再次读取换行符 getchar(); } int k; scanf("%d",&k); for(int i=0;i<k;i++){ // 用来定义大炮打的一泡的落点 int x,y; scanf("%d%d",&x,&y); int count=0; count += bang(x,y,2); count += bang(x-1,y,1); count += bang(x,y-1,1); count += bang(x,y+1,1); printf("%d\n",count); } return 0; }
字符串
字符串就是一串字符。
字符串的定义:
c语言:“abcdefeg” 或 字符数组
#include <stdio.h> int main(void) { // c 语言运行时内存有四个部分: 栈,堆,常量区,代码块 char *str ="hello world"; printf("%s\n",str); printf("%p\n",str); char *str2 ="hello world"; printf("%s\n",str2); printf("%p\n",str2); // 这的是s3放到了堆栈里了 char s3[] = "hello"; printf("%s\n",s3); printf("%p\n",s3); // s4数组是将常量池中的拿过来 char s4[] = "hello word"; printf("%s\n",s4); printf("%p\n",s4); printf("%d\n",sizeof(s3)); return 0; } // 输出: hello world 0x402004 hello world 0x402004 hello 0x7fffc8a4589a hello word 0x7fffc8a4588f 6 可以看到 *str 与*str 两个字符的指针指向的位置相同。
c++
#include <iostream> using namespace std; int main() { string name; cout << name <<"\n"; // 什么都没有是空字符串 string name2="llk"; cout << name2 <<"\n"; return 0; }
java
public void name(){ String name ="张三"; System.out.println(name); // java一般都是new出来的而这个却可以直接复值; // String name = "zhang" 这个其实就是在常量池中创建了一个对象,然后name引用指向常量池; 等价于 char data[] = {'z','h','a','n',y}; String namestr= new String(data); // String name = new String("zhang"); // 这个是在堆栈中创建一个新的对象将“zhang”放到静态区 } String str="hello";//直接赋值的方式,先在栈中创建一个对String类的对象的引用变量str,然后查找栈中有没有存放“hello”,如果没有就将“hello”存放在栈,并令star指向“hello”,如果已经有“hello”直接令str指向“hello” 通过构造方法创建字符串对象是在堆内存 String str=new String("hello");//实例化的方式 1)直接赋值(String str = "hello"):只开辟一块堆内存空间,并且会自动入池(到常量池中),不会产生垃圾。 2)构造方法(String str= new String("hello");):会开辟两块堆内存空间,其中一块堆内存会变成垃圾被系统回收,而且不能够自动入池(到常量池中),需要通过public String intern();方法进行手工入池(到常量池中)。new的每次都会创建对象,他只会存在堆中,每次调用一次就会创建一个新的对象。 将“hello”放到静态区 在开发的过程中不会采用构造方法进行字符串的实例化。
正则表达式与串的匹配
正则表达式是用于对字符串的匹配。
自动机
- 非确定型有限状态自动机(NFA):
- 确定型有限状态自动机(DFA):
// C++; #include <iostream> using namespace std; #include <regex> int main() { string str ="abcd"; regex r("[a-z]+"); // 匹配一个或多个字母 string email = "abc123@123.xm"; regex r1("[a-z0-9]+@[a-z0-9]+\\.[a-z0-9]+"); bool x=regex_match(str,r); cout << x <<endl; cout << regex_match(email,r1) << endl; return 0; } // java 使用类 pattern类 pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数 public static void main(String args[]){ String content = "I am noob " + "from runoob.com."; String pattern = ".*runoob.*"; boolean isMatch = Pattern.matches(pattern, content); System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch); } // python import re; re(r"正则表达式","匹配的字符")
这篇关于数据结构与算法实践系列文章(二)数组与字符串的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-21《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》简介
- 2024-12-21后台管理系统开发教程:新手入门全指南
- 2024-12-21后台开发教程:新手入门及实战指南
- 2024-12-21后台综合解决方案教程:新手入门指南
- 2024-12-21接口模块封装教程:新手必备指南
- 2024-12-21请求动作封装教程:新手必看指南
- 2024-12-21RBAC的权限教程:从入门到实践
- 2024-12-21登录鉴权实战:新手入门教程
- 2024-12-21动态权限实战入门指南
- 2024-12-21功能权限实战:新手入门指南