여기에 스레딩 할 필요가 없습니다. 제곱의 제곱의 합이 1이면 행복 할 수 있습니다. 시퀀스에 이미 테스트 된 번호가 포함되어있는 경우 그냥 끝내라. n이 행복하지 않은 경우 위키 피 디아에서
는
, 다음의 순서는 대신 발생이주기에 끝나는 무엇 1로 이동하지 않습니다.
public class Happy_numbers {
static int[]SQUARES={0,1,4,9,16,25,36,49,64,81};
public static boolean is_happy(int n){
return is_happy(n, new HashSet<Integer>());
}
public static boolean is_happy(int n, Collection<Integer> sofar){
if(n==1) return true;
else if(sofar.contains(n)) return false;
sofar.add(n);
if(n<10) {
return is_happy(SQUARES[n], sofar);
}
char[]digits=String.format("%s", n).toCharArray();
int s = 0;
for(char c:digits){
s+= SQUARES[Integer.valueOf(String.format("%s", c))];
}
return is_happy(s, sofar);
}
public static void main(String[]args){
Collection<Integer> c1 = Arrays.asList(
1, 7, 10, 13, 19, 23, 28, 31, 32, 44, 49, 68, 70, 79, 82, 86, 91, 94, 97,
100, 103, 109, 129, 130, 133, 139, 167, 176, 188, 190, 192, 193, 203, 208,
219, 226, 230, 236, 239, 262, 263, 280, 291, 293, 301, 302, 310, 313, 319,
320, 326, 329, 331, 338, 356, 362, 365, 367, 368, 376, 379, 383, 386, 391,
392, 397, 404, 409, 440, 446, 464, 469, 478, 487, 490, 496);
Collection<Integer> c2 = new ArrayList<Integer>(c1.size());
long t = System.currentTimeMillis();
int c = 1;
for(int i=0;i<500;i++){
if(is_happy(i)) {
System.out.print(i+", ");
if(c++ % 20 == 0) System.out.println();
c2.add(i);
}
}
t = System.currentTimeMillis()-t;
System.out.println("\nTIME : " + t);
System.out.println("Got them all < 500 : " + (c2.containsAll(c1) && c1.containsAll(c2)));
}
}
또한 더 많은 행복이고 당신이 번호 앞에 계산 한 경우, 필요 다시 같은 일을하지 할 수 있도록지도, 또는 캐싱 기술을 사용하여 향상시킬 수있다. wikipediea에서 500 이하
행복 번호는 : 1, 7, 10, 13, 19, 23, 28, 31, 32, 44, 49, 68, 70, 79, 82, 86, 91 , 94, 97, 100, 103, 109, 129, 130, 133, 139, 167, 176, 188, 190, 192, 193, 203, 208, 219, 226, 230, 236, 239, 262, 263 328, 356, 362, 365, 367, 368, 376, 379, 383, 386, 391, 392, 397, 404, 409, 440, 446, 464, 469, 478, 487, 490, 496 (OEIS 내의 서열 A007770).
및 위의 코드는 그래서 500
1, 7, 10, 13, 19, 23, 28, 31, 32, 44, 49, 68, 70, 79, 82, 86, 91, 94, 97, 100,
103, 109, 129, 130, 133, 139, 167, 176, 188, 190, 192, 193, 203, 208, 219, 226, 230, 236, 239, 262,
263, 280, 291, 293, 301, 302, 310, 313, 319, 320, 326, 329, 331, 338, 356, 362, 365, 367, 368, 376,
379, 383, 386, 391, 392, 397, 404, 409, 440, 446, 464, 469, 478, 487, 490, 496,
TIME : 435
Got them all < 500 : true
아래 모든 행복 번호를 얻기 위해 435 필요, 나는 적어도 지금까지 계산 된 것을 기억 허용하도록 코드를 일부 변경 한 현재 번호
public class Happy_numbers {
static class Ishappy extends Thread {
private Integer num;
private Thread main;
private volatile boolean out = false;
private boolean unhappy = false;
Ishappy(int i, Thread main) {
this.main = main;
num = i;
}
public boolean isUnhappy() {
return unhappy;
}
void Exit() {
out = true;
}
@Override
public void run() {
Set<Integer> sofar = new HashSet<Integer>();
while(!out && num != 1) {
unhappy = sofar.contains(num);
if(num == 1 || unhappy) {
main.interrupt();
break;
}
sofar.add(num);
String s = num.toString();
int temp = 0;
for(int i = 0 ; i < s.length(); i++) {
int x = Integer.parseInt(s.substring(i, i+1));
temp += x*x;
}
num = temp;
}
}
}
public static void main(String[] args) throws Exception{
byte path[] = null;
String s = "./data.txt";
FileInputStream fin = new FileInputStream(s);
InputStreamReader in = new InputStreamReader(fin);
BufferedReader br = new BufferedReader(in);
int num;
while((s = br.readLine()) != null) {
num = Integer.parseInt(s);
Ishappy ishappy = new Ishappy(num,Thread.currentThread());
ishappy.start();
ishappy.join();
if(ishappy.isUnhappy()){
System.out.println("Number ["+num+"] is not happy");
}else{
System.out.println("Number ["+num+"] is happy");
}
}
br.close();
in.close();
fin.close();
}
}
출력 내가 메인 스레드 나던이 중단 얻을 이유를 발견
Number [1] is happy
Number [7] is happy
Number [22] is not happy
편집
입니다.
메인 while 루프에서 num이 1인지 확인합니다. 하나 인 경우 num 값을 확인하고 기본 스레드를 인터럽트하는 if 조건을 얻지 못합니다. 여기
public class Happy_numbers {
public static void main(String[] args) throws IOException{
String s = "./data.txt";
FileInputStream fin = new FileInputStream(s);
InputStreamReader in = new InputStreamReader(fin);
BufferedReader br = new BufferedReader(in);
int num;
while((s = br.readLine()) != null) {
num = Integer.parseInt(s);
Ishappy ishappy = new Ishappy(num,Thread.currentThread());
ishappy.start();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println(1);
continue; // here is another problem, infinit loop
}
if(ishappy.isAlive()) {
ishappy.Exit();
System.out.println(0);
} else
System.out.println(11);
}
br.close();
in.close();
fin.close();
System.out.println("DONE");
}
}
및
는 Ihappy 클래스
class Ishappy extends Thread {
private volatile Integer num;
private Thread main;
private volatile boolean out = false;
Ishappy(int i, Thread main) {
this.main = main;
num = i;
}
void Exit() {
out = true;
}
@Override
public void run() {
while(!out) { /// <- here was the problem
if(num.intValue() == 1) { // since this condition will break out
main.interrupt(); // of the loop, you do not need it in the
break; // while condition
}
String s = num.toString();
int temp = 0;
for(int i = 0 ; i < s.length(); i++) {
int x = Integer.parseInt(s.substring(i, i+1));
temp += x*x;
}
num = temp;
}
}
}
이며, 출력은
1
1
0
DONE
귀하의 코드가이 클래스와 메소드의 이름을 지정하는 방식으로 인정 된 자바 코딩 표준을 위반입니다. 클래스 이름에는''_ ''문자가 포함되어서는 안되며 "camel case"를 사용해야하며 메서드 이름은 대문자로 시작하면 안됩니다. –
내 코드를 변경했습니다. 자본 'e'는 실제로 조금 공격적이었습니다. 내가 '-'를 사용하고있는 것은 파일의 이름을 유지하도록 요청 받았기 때문입니다. :) – user1232138