Java 测试4个数字,查看其是否有3个唯一的数字
我有点难以理解这个逻辑,以为我已经解决了,但现在我被难倒了 我们的目标是创建一个4位数的pin,有3个唯一的数字,1个可以是重复的。它们也可以按任何顺序排列。以下是我到目前为止的情况:Java 测试4个数字,查看其是否有3个唯一的数字,java,unit-testing,Java,Unit Testing,我有点难以理解这个逻辑,以为我已经解决了,但现在我被难倒了 我们的目标是创建一个4位数的pin,有3个唯一的数字,1个可以是重复的。它们也可以按任何顺序排列。以下是我到目前为止的情况: boolean UniqueNums(String nums) { for (int i=0; i < 3; i++) for (int j=i+1; j < 3; j++) if (nums.charAt(i) == nums.charAt(j))
boolean UniqueNums(String nums)
{
for (int i=0; i < 3; i++)
for (int j=i+1; j < 3; j++)
if (nums.charAt(i) == nums.charAt(j))
return false;
// If no duplicate characters encountered,
// return true
return true;
}
布尔唯一性(字符串nums)
{
对于(int i=0;i<3;i++)
对于(int j=i+1;j<3;j++)
if(nums.charAt(i)=nums.charAt(j))
返回false;
//如果没有遇到重复字符,
//返回真值
返回true;
}
因此,如果我通过数字1137
,它会失败,但其他类似的1371
通过
我觉得这是不同的,然后链接重复答案链接,因为我不试图在一行这样做,我不只是计数的次数出现。验证传递的值的代码行更长
任何帮助或建议都将不胜感激 对于循环(复杂度为
O(n^2)
),您可以使用哈希计算每个数字的出现次数,然后检查有效的pin码。以下是算法:
static boolean UniqueNums(String digit){
int array[] = new int[10];
for (int i=0;i<digit.length();i++){
array[digit.charAt(i)-48]++; //48 because ascii of 0 is 48
}
//Now check for frequency
int count = 0;
for (int i=0;i<10;i++){
if(array[i] > 2) return false;
if(array[i] == 2){
++count;
}
}
if(count <= 1) return true;
return false;
}
static boolean UniqueNums(字符串数字){
int数组[]=新的int[10];
对于(int i=0;i我认为在映射中保留计数器更简单:
public boolean UniqueNums(String pin){
if(pin.length() > 4) {
//pin too long
return false;
}
Map<Character, Integer> counters = new HashMap<>();
for(int i = 0; i < pin.length(); i++){
Character c = pin.charAt(i);
if(!Character.isDigit(c)){
//not a number.
return false;
}
counters.put(c, counters.getOrDefault(c,0) + 1);
if(counters.get(i) > 2){
// digit appear 3 times.
return false;
}
}
if(counters.keySet().size() < pin.length() - 1){
// not 3 unique numbers e.g 1122
return false;
}
return true;
}
public boolean UniqueNums(字符串pin){
如果(引脚长度()>4){
//别针太长
返回false;
}
映射计数器=新的HashMap();
对于(int i=0;i2){
//数字出现3次。
返回false;
}
}
if(counters.keySet().size()
关于:
boolean UniqueNums(String data) {
Set<Character> found = new HashSet<>();
int count = 0;
for (char c : data.toCharArray()) {
boolean noClash = found.add(c);
count += (noClash ? 0 : 1);
if (count == 2) {
return false;
}
}
return true;
}
布尔唯一性(字符串数据){
Set found=new HashSet();
整数计数=0;
for(char c:data.toCharArray()){
布尔noClash=found.add(c);
计数+=(NoFlash?0:1);
如果(计数=2){
返回false;
}
}
返回true;
}
- 1234返回true(无重复)
- 1231返回true(单个副本)
- 1221返回false(一对副本)
- 1112返回false(使用两次以上的数字)
如果您的PIN码长于4个字符,它也可以工作,只需要一个循环使其为O(n),并且快速失败您只需要另外一个int
来维护每个数字的位掩码。短的可以,但在Integer.bitCount()
调用中它会被加宽到int
boolean uniqueNums(String nums) {
int pin = Integer.parseInt(nums);
int mask = 0;
for (int i = 0; i < nums.length(); i++) {
mask |= 1 << pin % 10;
pin /= 10;
}
return Integer.bitCount(mask) >= 3;
}
由于涉及的数字限制,谓词可以从以下内容中缩减:
一个4位数的pin码,有3个唯一的数字,1个可以是重复的。它们也可以是任意顺序
到
有3个独特的字符
(您的代码不测试数字和长度,所以我假设其他代码也会这样做。)
您还可以按出现次数对数字进行分组,过滤最多出现2次的数字,使其计数与num length或length-1(一个副本)一样长:
boolean atMostOneOneDuplicate(字符串num){
长出现次数=个字符()
.mapToObj(i->(char)i)
.collect(Collectors.groupingBy(c->c,Collectors.counting())
.entrySet()
.stream()
.map(map.Entry::getValue)
.过滤器(v->v<3)
.count();
返回发生次数==num.length()| |发生次数==num.length()-1;
}使用地图记录事件
import java.util.HashMap;
import java.util.Map;
class Main{
public static void main(String[] args) {
System.out.println(isValid("1137"));
System.out.println(isValid("1371"));
System.out.println(isValid("1234"));
System.out.println(isValid("1222"));
}
public static boolean isValid(String num){
Map<Character,Integer> digitsWithNumberOfOccurances = new HashMap<>();
int numOfDigitsThatOccuredTwice = 0;
for(int i = 0; i < num.length(); i++){
char currentChar = num.charAt(i);
int currentNumberOfOccurences = digitsWithNumberOfOccurances.getOrDefault(currentChar,0);
currentNumberOfOccurences ++;
digitsWithNumberOfOccurances.put(currentChar,currentNumberOfOccurences);
if(currentNumberOfOccurences == 2){
numOfDigitsThatOccuredTwice++;
// only one digit can occur twice
if(numOfDigitsThatOccuredTwice > 1) {
return false;
}
}else if(currentNumberOfOccurences > 2){ // no digit can occur more than twice
return false;
}
}
return true;
}
}
import java.util.HashMap;
导入java.util.Map;
班长{
公共静态void main(字符串[]args){
System.out.println(isValid(“1137”));
System.out.println(isValid(“1371”));
System.out.println(isValid(“1234”));
System.out.println(isValid(“1222”));
}
公共静态布尔值isValid(字符串num){
Map Digits WithNumberOfOfOccurances=新HashMap();
int numodigits that occurrentedwice=0;
对于(int i=0;i2){//没有任何数字可以出现两次以上
返回false;
}
}
返回true;
}
}
您必须计算数字的出现次数,因此添加一个计数,如果计数大于2,则为false?是。您可以优化第一个循环,以仅测试第一个和第二个数字。您还可以创建一个重复数组,并比较一个循环中的每个元素……可能重复是这些检查在其他位置进行一个line解决方案-提出正确问题的完美示例我尝试编写与需求类似的代码,并根据需要进行功能分解,以获得一致的抽象级别。因此,我不理解此问题的返回值?@whisk做了一个小编辑,因为我之前的编辑弄错了。现在,如果至少有3个唯一值,则返回true在掩码
变量上作为位跟踪的数字,例如0
被跟踪.01
,1
被跟踪.010
,2
被跟踪为掩码.0100
。请参阅Integer.bitCou>文档
boolean hasAtLeastThreeUniqueCharacters = "1123".codePoints().distinct().count() >= 3;
boolean atMostOneOneDuplicate(String num) {
long occurences = num.chars()
.mapToObj(i -> (char) i)
.collect(Collectors.groupingBy(c -> c, Collectors.counting()))
.entrySet()
.stream()
.map(Map.Entry::getValue)
.filter(v -> v < 3)
.count();
return occurences == num.length() || occurences == num.length() - 1;
import java.util.HashMap;
import java.util.Map;
class Main{
public static void main(String[] args) {
System.out.println(isValid("1137"));
System.out.println(isValid("1371"));
System.out.println(isValid("1234"));
System.out.println(isValid("1222"));
}
public static boolean isValid(String num){
Map<Character,Integer> digitsWithNumberOfOccurances = new HashMap<>();
int numOfDigitsThatOccuredTwice = 0;
for(int i = 0; i < num.length(); i++){
char currentChar = num.charAt(i);
int currentNumberOfOccurences = digitsWithNumberOfOccurances.getOrDefault(currentChar,0);
currentNumberOfOccurences ++;
digitsWithNumberOfOccurances.put(currentChar,currentNumberOfOccurences);
if(currentNumberOfOccurences == 2){
numOfDigitsThatOccuredTwice++;
// only one digit can occur twice
if(numOfDigitsThatOccuredTwice > 1) {
return false;
}
}else if(currentNumberOfOccurences > 2){ // no digit can occur more than twice
return false;
}
}
return true;
}
}