字符串转整数
面试题67. 把字符串转换成整数
输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
输入: " -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 因此返回 INT_MIN (−231) 。
模拟 :
- 1.丢弃无用的空格字符
- 第一个非空字符为正负号时,与后面尽可能多的连续数字组合形成整数
- 除了数字 , 其他要被忽略。
class Solution {
int min = Integer.MIN_VALUE;
int max = Integer.MAX_VALUE;
public int strToInt(String str) {
char[] s = str.toCharArray();
int idx = 0;
int n = s.length;
while (idx < n && s[idx] == ' ') idx ++;
int sign = 1;
if (idx < n && (s[idx] == '+' || s[idx] == '-')) {
if (s[idx] == '-') sign = -1;
idx ++;
}
int val = 0;
while (idx < n && s[idx] >= '0' && s[idx] <= '9') {
if (val > (max - (s[idx] - '0')) / 10) {
if (sign == -1) return min;
else return max;
}
val *= 10;
val += s[idx] - '0';
idx ++;
}
val *= sign;
return val;
}
}
acwing 字符串哈希
题目链接
字符串哈希 采用的思想是 : 把字符串看作一个 b 进制数(b 取值于字符串长度) , 计算它在十进制下对p取模的值
简单说就是把一个字符串映射成一个数字 例子 就是把一个字符串如”ABC”映射成一个p进制的数字 “ABC” –> p^2+A + p^1+B + p^0+C = 哈希值, 一般p取131或13331 冲突概率极小 那冲突了怎么ban呢 , 取出来 在比较下稳妥。
如何 计算 字串hash 值?
有点类似前缀和的思想 “ABC” –> p^2+A + p^1+B + p^0+C = 哈希值
// 处理 进制关系。每段的hash 值
for (int i = 1 ;i <= n ; i ++) {
// 前缀和 思想
// 构造 进制 记录每个 i 的p次方 [1 位1] [2 位 P] [3 位 P²]····
// P的进制表
p[i] = p[i - 1] * P;
hash[i] = hash[i - 1] * P + s.charAt(i - 1);
}
如何计算 A 的哈希值? A 在0 位置 ABC 有 3 位 abc - a00 补位乘对应进制。类似于进制减法
计算公式如下:
hash[r1] - hash[l1 - 1] * p[r1 - l1 + 1]
代码
import java.util.*;
import java.io.*;
// 字符串哈希
// 简单说就是把一个字符串映射成一个数字
// 具体点,就是把一个字符串如”ABC”映射成一个p进制的数字
// “ABC” –> p^2+A + p^1+B + p^0+C = 哈希值, 一般p取131或13331
public class Main {
static int n;
static final int P = 131;
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
n = sc.nextInt();
int m = sc.nextInt();
String s = sc.next();
int[] p = new int[n + 10];
int[] hash = new int[ n + 10];
p[0] = 1;
// 处理 进制关系。每段的hash 值
for (int i = 1 ;i <= n ; i ++) {
// 前缀和 思想
// 构造 进制 记录每个 i 的p次方 1 位 0 2 位1 ····
p[i] = p[i - 1] * P;
hash[i] = hash[i - 1] * P + s.charAt(i - 1);
}
while (m -- > 0) {
int l1 = sc.nextInt();
int r1 = sc.nextInt();
int l2 = sc.nextInt();
int r2 = sc.nextInt();
// System.out.println( hash[r1] - hash[l1 - 1] * p[r1 - l1 + 1]);
// System.out.println( hash[r2] - hash[l2 - 1] * p[r2 - l2 + 1]);
String out = hash[r1] - hash[l1 - 1] * p[r1 - l1 + 1] == hash[r2] - hash[l2 - 1] * p[r2 - l2 + 1] ? "Yes" : "No";
System.out.println(out);
}
}
}
28. 找出字符串中第一个匹配项的下标
class Solution {
static final int P = 131;
public int strStr(String haystack, String needle) {
int n = haystack.length();
int m = needle.length();
// 进制表
int[] p = new int[ n + 1];
int[] hashA = new int[n + 1];
p[0] = 1;
// 求 haystack 字符串 hash
// 进制表 n 一定 大于 m 放在n 求了
for (int i = 1 ; i <= n ; i ++) {
p[i] = p[i - 1] * P;
//
hashA[i] = hashA[i - 1] * P + haystack.charAt(i - 1);
}
int[] hashB = new int[m + 1];
for (int i = 1 ; i <= m ; i ++) {
hashB[i] = hashB[i - 1] * P + needle.charAt(i - 1);
}
// 枚举比较hash 值
for (int i = m ; i <= n ; i ++) {
// hahs 从 1 开始存 最少是1
if (hash(p,hashA,i - m + 1,i) == hashB[m] && haystack.substring(i - m, i).equals(needle)) return i - m;
}
return -1;
}
int hash(int[] p , int[] hash , int l , int r ) {
return hash[r] - hash[l - 1] * p[r - l + 1];
}
}