1、字符串逆序相关:
1)逆序长字符串,包含空格:
import java.util.Scanner;
public class TestString2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入字符串");
String inputString = scanner.nextLine();
System.out.println("反转后的字符串");
String outputString = reverse(inputString);
System.out.println(outputString);
}
public static String reverse(String str) {
int length = str.length();
if (length > 100 || length < 0) {
System.out.println("输入不合法");
return null;
}
StringBuilder stringBuilder = new StringBuilder();
for (int i = length; i > 0 ; i--) {
stringBuilder.append(str.charAt(i - 1));
}
return stringBuilder.toString();
}
}
2)逆序一个句子:如输入"i am a boy",输出"boy a am i"
/**
* 逆序句子,如"I am a boy"输出"boy a am I"
* @param sentence 原始句子字符串
* @param cut 每个单词之间的分隔符
* @return
*/
public static String reverseSentence(String sentence, String cut) {
String[] words = sentence.split(cut);
StringBuilder builder = new StringBuilder();
// 逆序遍历数组;注意起始为length - 1,终止为0
for (int i = words.length - 1; i >= 0 ; i--) {
builder.append(words[i]);
builder.append(cut);
}
System.out.println(builder.toString());
// 注意逆序后末尾多了一个分隔符,需要去掉
return builder.substring(0, builder.length() -cut.length());
}
3)逆序句子中的每一个单词:如输入"i am a boy",输出"i ma a yob":先将句子以分隔符转为数组,对数组中每个元素(单词)逆序,然后以分隔符重组为句子
2、对整数逆序,且取出前位的0:
//将任意位数的整数逆序,且去除前位的0
public static int rev(int x) {
StringBuilder stringBuilder = new StringBuilder(x + "");
stringBuilder.reverse();
return Integer.valueOf(stringBuilder.toString());
}
3、统计字符串中字符出现的次数:
public static void getHashMap(String string){
HashMap<Object,Integer> hashMap = new HashMap<>();
// 忽略空格
string = string.replace(" ", "");
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (hashMap.isEmpty())
hashMap.put(c, 1);
else {
if (hashMap.containsKey(c)){
Integer value = hashMap.get(c);
hashMap.put(c, value+1);
} else {
hashMap.put(c, 1);
}
}
}
Set<Object> keySet = hashMap.keySet();
System.out.print("[");
StringBuilder stringBuilder = new StringBuilder();
for (Object key : keySet){
Integer value = hashMap.get(key);
stringBuilder.append(key + ":" + value + ",");
}
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
System.out.print(stringBuilder + "]");
}
4、拼接不同类型的字符串:
// Object用来保存拼接后的数组
//输出数组Arrays.toString(concat(intArray, stringArray));格式为[,,,],字符串没有双引号
//要输出带双引号的字符串,则字符串定义时为"\"a\""即转义双引号
public static Object[] concat(int[] intArray, String[] stringArray){
int length1 = intArray.length;
int length2 = stringArray.length;
Object[] o = new Object[length1 + length2];
for (int i = 0; i < length1; i++){
o[i] = intArray[i];
}
for (int i = length1; i < length1 + length2; i++){
o[i] = stringArray[i - length1];
}
return o;
}
5、判断是否回文字符串:
boolean isHuiWen(String text) {
int length = text.length();
for (int i = 0; i < length / 2; i++) {
if (text.toCharArray()[i] != text.toCharArray()[length - i - 1]) {
return false;
}
}
return true;
}
6、指定字符、字符串的查找与统计:
6.1 统计数组中所有元素出现的次数/统计字符串中所有字符出现的次数(将参数换为String且转为char[],map类型为<Character,Integer);用map保存数组元素和出现次数:遍历数组元素,全部放入map的key,而之前先判断map中该字符出现的次数,次数作value;map的key作为set,便于迭代) :
// 统计字符串中出现最多的字符的次数
// 初级写法:o(n) = n*n;存在问题:当出现次数最多的不止一个字符时,输出的是最后一个
public static int count(String str) {
char maxCountChar = str.charAt(0); // 初始默认出现次数最多的为第一个字符
int maxCount = 0;
for (int i = 0; i < str.length(); i++) {
char tempChar = str.charAt(i);
int tempCount = 0;
// 内层循环,统计在i处字符的出现次数
for (int j = 0; j < str.length(); j++) {
if (tempChar == str.charAt(j)) {
tempCount++;
}
}
// 对比在i处字符出现次数与最大次数,修改最大次数值;修改默认出现最多的字符
if (tempCount >= maxCount) {
maxCount = tempCount;
maxCountChar = tempChar;
}
}
System.out.println("出现最多次数 " + maxCount + " 次的字符是 " + maxCountChar);
return maxCount;
}
// 优化
public static void countAll(String[] stringArr) {
Map<String, Integer> map=new HashMap<String, Integer>();
for(String string:stringArr){
Integer integer=map.get(string);
if (integer==null) {
map.put(string, 1);
} else {
map.put(string, integer+1);
}
//找出所有包含某个字符(或子串)的字符串
for(int i=0;i<string.length();i++){
if(‘目标字符’==string.indexOf())
//if(“子串”.equals(string.subString(i,i+子串.length()))),注意此时for循环下标会越界,应减去子串长度
new StringBuffer.append(string+””);//最后显示这个StringBuffer
}
}
Iterator iterator=map.keySet().iterator();
while(iterator.hasNext()){
Object key=iterator.next();
int count=map.get(key);
System.err.println("元素"+key+"出现的次数: "+count);
}
}
6.2、指定字符的查找与统计:
1)找出第一个没有出现重复,即第一个只出现过一次的字符:在利用map统计字符次数的基础上,输出map中value值为1的key即可;另一种思想是,字符第一次出现的位置 == 字符最后一次出现的位置,说明该字符只出现一次,配合for循环,在首次找到后break即可:
if (str.indexOf(str.charAt(i)) == str.lastIndexOf(str(charAt(i)))) {
System.out.println(str.charAt(i));
break;
}
2)利用Set的元素不重复性找出第一次出现重复的字符,如"abccba"中第一次出现重复的是'c':
Set<Character> set = new HashSet<>();
for (int i = 0; i < string.length(); i++) {
// 添加元素时返回false,说明set中已经存在该元素
if (!set.add(string.charAt(i))) {
System.out.println(string.charAt(i));
break;
}
}
3)统计号码中每个数字出现的次数,并按阿拉伯数字顺序对出现的数字排序输出; 这用map方式统计此处,然后对value排序的话会变得复杂;使用特殊技巧:
public static void countNumber(String number) {
int[] count = new int[10]; // 用数组保存0-9这10个数字出现的次数,如第一个元素count[0]保存数字0出现的次数;初始该数组所有元素为0
for (int i = 0; i < number.length(); i++) {
char c = number.charAt(i);
count[c - '0']++; // 如i=0即取出号码第一个数字1,(转为int类型后),count[1]++,即数组的第二个元素的0++为1
}
for (int i = 0; i < count.length; i++) {
if (count[i] > 0) { // 遍历数组,该元素不为0,即表示出现次数不为0,即数字出现过
System.out.println("数字 " + i + " 出现了 " + count[i] + "次");
}
}
}
4)统计文件中某个字符串出现的次数:
public static int statisticalNumber(String fileName,String str) throws Exception {
int count = 0;
BufferedReader bf = new BufferedReader(new InputStreamReader(new FileInputStream(fileName))); //构造文件输出流
String readLine ;
StringBuilder sb = new StringBuilder();
while((readLine = bf.readLine() )!= null) {
sb.append(readLine); //将数数据写入添加到缓冲字符串
}
//方式1
int a = 0;
while((a = sb.indexOf(str)) != -1) {
sb = sb.delete(a, a + str.length()); //查找字符串在缓冲字符串中的位置,查到则表示存在;删除,统计删除次数
count++;
}
//方式2:将sb再转为长String,并用str做切割符,切成字符串数组后数组长度-1即表示切割了几次,即string出现次数
count=sb.toString().split(str).length-1;
//使用正则表达式相关API
Pattern p=Pattern.compile(str);
Matcher m=p.mathcer(sb);//放在长串中匹配
while(m.find())
num++;
return count;
}
//filePath=”F:/test.txt”等价“F:\\test.txt”,第一个\是转义字符
7、按照字节数截取字符串;有中文时不能出现半个字符:
/**
* 按照字节数截取字符串;有中文时不能出现半个字符
* @param originString 目标字符串
* @param substringSize 截取大小,X字节
*/
public static void substringByBytes(String originString, int substringSize) {
// 已经截取的字节数
int substringSizeChanged = 0;
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < originString.length(); i++) {
// 每一个字符的字节数,如英文字符字节数为1,中文字符字节数为2或3
int charLength = String.valueOf(originString.charAt(i)).getBytes().length;
System.out.println(charLength);
// 已经截取的字节数 + 下一个字符的字节 <= 要求的截取字节数,说明下一个字符还可以截取
if ((substringSizeChanged + charLength) <= substringSize) {
substringSizeChanged += charLength;
stringBuilder.append(originString.charAt(i));
} else {
break;
}
System.out.println(stringBuilder.toString());
}
}
8、判断字符串是否符合ipv4:
/**
* 判断是否合法的IPV4地址:以.分隔的4个0-255范围内的数字
* @param ipv4
* @return
*/
public static boolean isIPV4(String ipv4) {
String[] numbers = ipv4.split("\\.");
if (numbers.length != 4) {
return false;
}
for (String number: numbers) {
Integer num = Integer.parseInt(number);
if (num > 255 || num < 0) {
return false;
}
// 避免"0X"形式的数字出现
if (!number.equals("0") && number.startsWith("0")) {
return false;
}
}
return true;
}
2 数组
2.1 Arrays基本用法
import java.util.Arrays;
public class Test02 {
public static void main(String[] args) {
float result0 = add(1,2.0f);
float result1 = add(1,2);
System.out.println(result0);
System.out.println(result1);
//Arrays API
int[] arr = {1,2,3,4,7,8,9,10,5,6};
int key = Arrays.binarySearch(arr,6);
System.out.println(key);
// 输出数组:1 2 3 4 5...
for (int i: arr){
System.out.print(i + "\t");
}
// 转为字符串输出:[1,2,3,4,5,...],即toString()方法会添加[]和逗号分隔符
System.out.println(Arrays.toString(arr));
// 排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
// 复制
int[] arrCopy0 = Arrays.copyOf(arr,5);
int[] arrCopy1 = Arrays.copyOfRange(arr,2,8);
System.out.println(Arrays.toString(arrCopy0));
System.out.println(Arrays.toString(arrCopy1));
// 填充
Arrays.fill(arr,0);
System.out.println(Arrays.toString(arr));
}
public static float add(int a,float b) {
return a + b;
}
}
2.2 二维数组与元素查找
/**
* 在n * m的二位数组/矩阵中,每一行从左到右递增,每一列从上到下递增;
* 求该数组中是否包含指定元素key;
* [1,3,4,7,9],
* [2,5,6,15,18],
* [3,7,8,18,20]
* 应该充分利用此数组的特性;如果单纯每一行每一列的遍历,则不够优化;
* 观察发现,第一行+最后一列元素是一个递增顺序
* 当key小于矩阵的右上角时,如key<9,则一定在9所在列的左边,即9所在列可以舍去,于是矩阵缩小;
* 同理,当key大于右上角时,则那一行可以舍去,矩阵缩小;
* 如此反复缩减,最终key=右上角时,得解;
*/
public static boolean findNumberIn2DArray(int[][] matrix, int target) {
if ((matrix == null || matrix.length == 0) || (matrix.length == 1 && matrix[0].length == 0)) {
return false;
}
int i = 0;
int j = matrix[0].length - 1; // [i,j]起始坐标为第一行最后一列即右上角
while (i <= matrix.length - 1 && j >= 0) {
if (target == matrix[i][j])
return true;
if (target < matrix[i][j])
j--;
else i++;
}
return false;
}
// 二维数组的初始化
int[][] array = {{1,3,4,7,9},{2,5,6,15,18},{3,7,8,18,20}};
-
给定一个整数数组nums和一个目标值target,找出在该数组中,和为target的两个整数并返回其下标;如[2,7,11,15]和target,返回[0,1];假设每种输入只会对应一个答案,但数组中每一个元素不能使用两遍
public static void main(String[] args) { int[] nums = new int[]{2, 7, 11, 15}; int target = 9; int[] index = sum1(nums, target); for (int element: index) { System.out.println(element); } } // 暴力解法:时间复杂度为o(n * n) public static int[] sum1(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { if (target - nums[i] == nums[j]) { return new int[]{i, j}; } } } return null; } // 优化解法:hash查找:o(n) public static int[] sum2(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int partnerNumber = target - nums[i]; if (map.containsKey(partnerNumber)) { return new int[]{map.get(partnerNumber), i}; } map.put(nums[i], i); } return null; }