char array to int array conversion in java generates null pointer exception - java

I am trying to run the following HillCipher program but it is terminated after the line of conversion of char array to int array and after compilation of that code it shows me null pointer exception.It works fine if I replace int array with int variable,but I need int array in this code to encrypt the data:
try{
do//key
{
System.out.println("Enter Key of length 4 character : ");
sKey=(new BufferedReader(new InputStreamReader(System.in))).readLine();
cKey=new char[2][2];
}while(!checkKey());
}
catch(Exception e)
{}
}
boolean checkKey()
{
boolean flag=true;
if(sKey.length()!=4)
flag=false;
int k=0;
int temp;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
cKey[i][j]=sKey.charAt(k);
k++;
iKey[i][j]=(int)cKey[i][j]; //program is terminated after this line
iKey[i][j]-=97;
if(cKey[i][j]<97 || cKey[i][j]>122)
{
flag=false;
break;
}
}
if(flag==false)
{
System.out.println("flag: "+flag);
break;
}
}
int d;
if((d=iKey[0][0]*iKey[1][1]-iKey[1][0]*iKey[0][1])==0)
flag=false;
if(flag==false)
System.out.println("Invalid Key!! ");
else
keygen(d);
return flag;
}
void keygen(int d)
{
if (d<0)
d*=-1;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
if(i==0 && j==0)
iDKey[i][j]=iKey[1][1]/d;
else if(i==1 && j==1)
iDKey[i][j]=iKey[0][0]/d;
else
iDKey[i][j]=-iKey[i][j]/d;
}
}
}
String encrypt()
{
int l;
if(sPlainTxt.length()%2==0)
l=sPlainTxt.length();
else
l=sPlainTxt.length()+1;
int temp1,temp2,ans;
for(int i=0;i<l;i+=2)
{
temp1=(int)cPlainTxt[i]-97;
temp2=(int)cPlainTxt[i+1]-97;
ans=iKey[0][0]*temp1+iKey[0][1]*temp2;
System.out.println(ans);
ans%=26;
ans+=65;
cCipherTxt[i]=(char)ans;
cCipherTxt[i+1]=(char)((iKey[1][0]*temp1+iKey[1][1]*temp2)%26+65);
}
sCipherTxt=new String(cCipherTxt);
return sCipherTxt;
}
}

You never assign a value to iKey, so it has its initial default value of null - it's as simple as that. You need to create a new array, e.g.
// Given that you've hard-coded the length of cKey as well...
iKey = new int[2][2];
I'd also strongly urge you not to catch exceptions like this:
catch(Exception e)
{}

Related

the error when i change a number in decimal base to another base

I am writing a java code to Change a number from decimal base to another base.
But I don't know why the program runs wrong. I think the error comes from function Prin_as. Can anyone tell me why ?
Below is my code,
import java.util.Scanner;
public class bai2chuyendoi {
public static void main(String[] args) {
int a, b;
System.out.println("Number in decimal base:");
a = Enter();
System.out.println("Other base :");
b = Enter();
Change_base (a, b);
}
public static int Enter() {
int n = 0;
boolean check = false;
while (!check) {
Scanner sc = new Scanner(System.in);
try {
n = sc.nextInt();
check = true;
} catch (Exception e) {
System.out.println("Enter again:");
sc.nextLine();
}
}
return n;
}
public static void Change_base(int a, int b) {
int i = 0;
int[] c = new int[8];
while (a != 0) {
c[i] = a % b;
a = a / b;
i++;
}
while (i >= 0) {
--i;
if (c[i] < 10) {
System.out.print(c[i]);
} else {
System.out.print((char) (c[i] + 55));
}
}
}
}
The error was in Change_base method in second while loop.
You need decrement 'i' and check that i >= 0, but you didn't.
while (--i >= 0) {
if (c[i] < 10) {
System.out.print(c[i]);
} else {
System.out.print((char) (c[i] + 55));
}
}

How can I continue permutation/combination where I stopped the program?

It's my second time asking here and straight to the point. I can't seem to find a solution and I know it's not impossible. I wrote a java program that can generate a set of combination of any length, when I stop the program I don't want to start from the beginning how can I pick up from where I stopped?
Thanks.
Example (for length 3):
If I start from aaa ==> 9zI and I stop the program here, I don't want to start from aaa all over but start from 9zI and continue to 999. I just want to continue from where I left off.
public class Main {
public static void main(String[] args) {
S_Permutation sp = new S_Permutation();
String text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
FileClass.fileExist("new.txt", true);
System.out.println("");
sp.permutation(text, "", 7, "sha256.txt","Kaaaaaa");
}
}
=====================================================================
public class S_Permutation {
private List<String> permutation;
public S_Permutation() {
permutation = new ArrayList<>();
}
public boolean saveThis(String words, char a, int limit) {
int count = 0;
limit++;
for (char character : words.toCharArray()) {
if (count == limit) {
return false;
}
if (character == a) {
count++;
} else {
count = 0;
}
}
return count < limit;
}
private int counter = 0;
private boolean seen = false;
public void permutation(String str, String prefix, int lengthOfPermutationString, String filename, String startPoint) {
if (prefix.equalsIgnoreCase(startPoint))
{
seen = true;
}
if (counter == 0) {
if (startPoint.length() != lengthOfPermutationString) {
for (int i = startPoint.length(); i < lengthOfPermutationString; i++) {
startPoint += str.charAt(0);
}
}
counter = -45;
}
if (prefix.length() == lengthOfPermutationString) {
boolean savethis = true;
for (int i = 0; i < prefix.length(); i++) {
savethis = this.saveThis(prefix, prefix.charAt(i), 13);
if (!savethis) {
break;
}
}
if (savethis && seen) {
System.out.println(prefix);
//permutation.add(prefix);
}
} else {
for (int i = 0; i < str.length(); i++) {
if (permutation.size() == 1000) {
FileClass.WriteFile("new.txt", permutation);
permutation.clear();
}
permutation(str, prefix + str.charAt(i), lengthOfPermutationString, filename, startPoint);
}
FileClass.WriteFile("new.txt", permutation);
permutation.clear();
}
}
}
=========================================================================
public class FileClass {
public static boolean WriteFile(String filename, List<String> doc) {
try {
if (!filename.contains(".txt")) {
filename += ".txt";
}
RandomAccessFile raf = new RandomAccessFile(filename, "rw");
String writer = "";
writer = doc.stream().map((string) -> string + "\n").reduce(writer, String::concat);
raf.seek(raf.length());
raf.writeBytes(writer);
raf.close();
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println("Error");
new Scanner(System.in).nextLine();
return false;
}
return true;
}
static RandomAccessFile raf;
public static boolean fileExist(String filename, boolean delete){
File file = new File(filename);
if (file.exists() && delete)
{
return file.delete();
}
return file.exists();
}
public static void WriteFile(String filename, String text) {
try {
if (!filename.contains(".txt")) {
filename += ".txt";
}
raf = new RandomAccessFile(filename, "rw");
long length = raf.length();
raf.setLength(length + 1);
raf.seek(raf.length());
raf.writeBytes(text + "\n");
} catch (Exception e) {
}
}
private static void write(List<String> records, Writer writer) throws IOException {
for (String record : records) {
writer.write(record);
}
writer.flush();
writer.close();
}
public static void stringWriter(List<String> records, String filename) {
try {
File file = new File(filename);
FileWriter writer = new FileWriter(file, true);
write(records, writer);
} catch (Exception ex) {
System.out.println(ex.getMessage());
new Scanner(System.in).nextLine();
}
}
public static boolean CloseFile() {
try {
raf.close();
return true;
} catch (Exception e) {
return false;
}
}
}
In order to add a "Resume" mechanism, you need to make your program idempotent. One way to do it, is instead of saving the permutations - save to file the parameters that are sent to permutation on each iteration:
now each time that the program starts, it will check what were the last parameters that permutation was called with (the last line in the file), and start from there (when the program starts on the first time, nothing will be written in the file - so it will start from the beginning).
After that the recursion finished, we can call another method that will go over the lines of the file, and read only the permutations (ignoring the other parameters) and write them into a cleaner "final_result.txt" file.
Needless to say that this implementation is more costly (all the additional reads and write from disc) but that's the tradeoff for having it support "resume" operation.
To save/restore process in the middle of its work, you need something we can call a "state" and implement generating combinations in iterative way.
In my implementation the "state" is pos object (I assume set and k will not change on "resume").
My implementation of the problem would be following:
public class RepeatComb {
private int[] pos;
private String set;
public RepeatComb(String set, int k) {
this.set = set;
pos = new int[k];
}
public int[] getState() {return Arrays.copyOf(pos, pos.length);}
public void resume(int[] a) {pos = Arrays.copyOf(a,a.length);}
public boolean next() {
int i = pos.length-1;
for (int maxpos = set.length()-1; pos[i] >= maxpos; ) {
if (i==0) return false;
--i;
}
++pos[i];
while (++i < pos.length) pos[i]=0;
return true;
}
public String getCur() {
StringBuilder s = new StringBuilder(pos.length);
for (int i=0; i < pos.length; ++i)
s.append(set.charAt(pos[i]));
return s.toString();
}
public static void main(String[] args) {
int[] state;
String text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
RepeatComb comb = new RepeatComb(text, 3);
int stop = 10; //break after 10
do {
if (stop-- == 0) break;
System.out.println(comb.getCur());
} while (comb.next());
//save state
state = comb.getState();
System.out.println("---------");
//resume (with the same args: text,3)
stop = 10; //break after 10
comb = new RepeatComb(text, 3);
comb.resume(state); // resume here
do {
if (stop-- == 0) break;
System.out.println(comb.getCur());
} while (comb.next());
}
}
Update: I've added functions for getting state and resuming from it
and example of use. state array can be saved in file, then restored.

"Race" appearance. How to create a consistent line length

I have created the following but need the output line to maintain a consistent width to give the appearance of a race. I also need to ensure that the racers do not slip back past the start.
Currently, the output plots correctly, but the line only extends to the racers position.
Also, when there is a "slip" it appears that the racer sometimes moves back to start. I'm not sure if that is solved with a consistent length of "race track" as well.
import java.util.*;
public class Race {
public static void main(String []args) {
int finish=70,tort=1,hare=1,rtime=0;
System.out.println("ON YOUR MARK, GET SET\nBANG !!!!!\nAND THEY'RE OFF !!!!!\n");
do{
hare=movehare(hare);
tort=movetort(tort);
print(tort,hare);
rtime++;
}
while(tort<finish&&hare<finish);
if(tort>hare ){
System.out.println("\nTORTOISE WINS!\n");
}
else if(tort<hare ){
System.out.println("\nHARE WINS!\n");
}
else{
System.out.println("IT\'S A TIE!\n");
}
}
public static void print(int t,int h){
int i;
if(h==t){
for(i=0;i<h;i++)
System.out.print("_");
System.out.println("OUCH!!!");
}
else if(h<t){
for(i=0;i<h;i++)
System.out.print("_");
System.out.print("H");
for(i=0;i<(t-h);i++)
System.out.print("_");
System.out.print("T");
}
else{
for(i=0;i<t;i++)
System.out.print("_");
System.out.print("T");
for(i=0;i<(h-t);i++)
System.out.print("_");
System.out.print("H");
}
System.out.println();
}
public static int movehare(int r ){
int num;
num=(int)(Math.random()*10);
if(num<2){
r-=2;
}
else if(num<5){
r++;
}
else if(num<6){
r-=12;
}
else if(num<8){
r+=9;
}
if(r< 1 ){
r=1;
}
return r;
}
public static int movetort(int t){
int num;
num=(int)(Math.random()*10);
if(num<5){
t+=3;
}
else if(num<7){
t-= 6;
}
else{
t++;
}
if(t<1){
t=1;
}
return t;
}
}
You can print extra "_" after each of the IF branches in your print method
if(h != t){
for(i = Math.max(h,t); i < 70; i++){
System.out.print("_");
}
}
Note: The line breaks will be off when the H == T because you print "Ouch!!!", so you'll have to check for that and accommodate.

Input Validation - Only Integers?

I'm working on a project where the Java code must find the total,
average, etc. of exam scores. It reads the scores from an external
file.
I've been trying for hours to find a way to edit my code so that it ignores any data in the file that is not an integer between 0-100. But I can't. Checked all the questions and answers on Stack Overflow, and I can't find any answers that would help my specific situation. Here's the while loop of my code that I'm trying to work with:
Scanner reader = new Scanner(file);
while (reader.hasNext())
{
String line = reader.nextLine();
nextScore = Integer.parseInt(line);
System.out.println(nextScore);
sum = nextScore + sum;
totalNumberOfScores++;
if (nextScore > maxScore)
{
maxScore = nextScore;
}
else if (nextScore < minScore)
{
minScore = nextScore;
}
if (nextScore >= A)
{
countA++;
}
else if (nextScore >= B)
{
countB++;
}
else if (nextScore >= C)
{
countC++;
}
else if (nextScore >= D)
{
countD++;
}
else
{
countF++;
}
}
reader.close();
Can anyone help ?
if(isInteger(line)){
nextScore = Integer.parse(line);
}
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
} catch(NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
then you can do this
boolean isNumber = false;
for(int i = 0; i < line.length; i++){
try{
Integer.parseInt(String.valueOf(line.charAt(i)));
}catch(Exception e){
isNumber = false;
break;
}
}
if(isNumber){
Integer.parse(line);
}
or even
boolean isNumber = true;
try{
Integer.praseInt(line);
}catch(Exception e){
isNumber = false;
}
if(isNumber){
//everthing else
}
I would use a try-with-resources Statement to close the Scanner when through reading. Next, you need to define your min, max, total and lines count outside the loop. You could default min to the maximum possible value, and max to the minimum; then use Math.max(int,int) and Math.min(int,int) to set the max and min respectively. Then, you need to validate that you read an int and that is in the correct range before processing it as input. Something like,
try (Scanner reader = new Scanner(file)) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
int total = 0;
int lines = 0;
int countA = 0, countB = 0, countC = 0, countD = 0, countF = 0;
while (reader.hasNextLine()) {
String line = reader.nextLine();
try {
int nextScore = Integer.parseInt(line);
if (nextScore >= 0 && nextScore <= 100) {
min = Math.min(nextScore, min);
max = Math.max(nextScore, max);
total += nextScore;
lines++;
if (nextScore >= A) {
countA++;
} else if (nextScore >= B) {
countB++;
} else if (nextScore >= C) {
countC++;
} else if (nextScore >= D) {
countD++;
} else {
countF++;
}
}
} catch (NumberFormatException nfe) {
}
}
System.out.printf("Min: %d, Max: %d, Total: %d, Lines: %d, Average: %.2f%n",
min, max, total, lines, total / (float) lines);
System.out.printf("%d As, %d Bs, %d Cs, %d Ds, %d Fs", countA, countB,
countC, countD, countF);
} catch (IOException e) {
e.printStackTrace();
}

App is crashing when I convert string to int

I use two dimensional array and suppose I want to convert a string to int in a specific element
like that arr[0][1]="12";. I am using this
int id=0; String[][] description=new String[obj.length][];
String[] temp;
for(int i=0; i<obj.length; i++) {
da[i]=obj[i].toString(); temp=da[i].split(",");
description[i]=new String[temp.length];
for(int j=0; j<temp.length; j++) {
// id=new String[temp.length];
description[i][j]=temp[j];
if(j==0) {
try {
id=Integer.parseInt(description[i][j]);
}
catch(NumberFormatException nfe) { // Log exception. }
//id=Integer.parseInt(description[i][j].toString());
Toast.makeText(getApplicationContext(),id, Toast.LENGTH_SHORT).show();
}
}
But it gives null pointer exception.
check if its not null then cast to integer:
try {
if(description[i][j]!=null && description[i][j].length()>0){
id=Integer.parseInt(description[i][j]);
Toast.makeText(getApplicationContext(),id, Toast.LENGTH_SHORT).show();
}
}
instead of
try {
id=Integer.parseInt(description[i][j]);
}
i hope its work but description[i][j] must returns string.
if id getting value then print toast.otherwise no toast print..

Categories