Hello there,
My lab assignment is to take two strings, convert them into linkedLists and add the linked lists up. I have managed to get them to a level where they could be added together but you can't carryover. I have been working on that part and can't seem to figure it out.
The code is typed below. Thank you!
I reverse the strings when they get inputed in. the output string also needs to be reversed.
Code package linkedlist;
import java.util.Scanner;
/**
*
* #author Spock-II
*/
public class LinkedList {
public static LinkedInt Trueadd(LinkedInt A, LinkedInt B) {
LinkedInt a = A;
LinkedInt b = B;
int next;
LinkedInt sum = new LinkedInt();
System.out.println("Switches!");
if (a.size() > b.size()) {
System.out.println("size: " + (a.size() - b.size()));
int limit = a.size() - b.size();
for (int i = 0; i < limit; i++) {
b.addToLinkList("0", i);
System.out.println("inloop b");
System.out.println("i : " + i);
}
System.out.println("loop complete");
} else if (a.size() < b.size()) {
System.out.println("size: " + (b.size() - a.size()));
int limit = b.size() - a.size();
for (int i = 0; i < limit; i++) {
a.addToLinkList("0", i);
System.out.println("inloop b");
System.out.println("i : " + i);
}
System.out.println("loop complete");
}
System.out.println("Switch overcame");
int carryover = 0;
while (a.head != null & b.head != null) {
String[] carryCheck = (Integer.valueOf(a.head.getItem()) + Integer.valueOf(b.head.getItem()) + "").split("");
if (carryCheck.length == 2) {
sum.addToLinkList((Integer.valueOf(carryCheck[1])+carryover)+"", 0);
carryover = Integer.valueOf(carryCheck[0]);
} else {
int i = Integer.valueOf(a.head.getItem()) + Integer.valueOf(b.head.getItem());
sum.addToLinkList(i + "", 0);
}
System.out.println("a: " + a.head.getItem());
System.out.println("b: " + b.head.getItem());
a.head = a.head.getLink();
b.head = b.head.getLink();
}
System.out.println("Completed");
return sum;
}
public static LinkedInt subtract(LinkedInt a, LinkedInt b) {
a.combine();
b.combine();
LinkedInt difference = new LinkedInt(a.x - b.x);
difference.combine();
return difference;
}
public static LinkedInt multiply(LinkedInt a, LinkedInt b) {
a.combine();
b.combine();
LinkedInt product = new LinkedInt(a.x + b.x);
product.combine();
return product;
}
public static LinkedInt divide(LinkedInt a, LinkedInt b) {
a.combine();
b.combine();
LinkedInt sum = new LinkedInt(a.x + b.x);
sum.combine();
return sum;
}
public static LinkedInt modulus(LinkedInt a, LinkedInt b) {
a.combine();
b.combine();
LinkedInt rem = new LinkedInt(a.x + b.x);
rem.combine();
return rem;
}
public static void main(String[] args) {
// TODO code application logic here
Scanner i1 = new Scanner(System.in);
System.out.print("Please enter the first no. : ");
int a = i1.nextInt();
Scanner i2 = new Scanner(System.in);
System.out.print("Please enter the second no. : ");
int b = i2.nextInt();
System.out.println();
LinkedInt a1 = new LinkedInt(a);
LinkedInt a2 = new LinkedInt(b);
a1 = a1.populate();
a2 = a2.populate();
a1.combine();
a2.combine();
LinkedInt sum = Trueadd(a1, a2);
sum.combine2();
// LinkedInt sum = a1;
}
}
`
I don't know the exact structure of your LinkedInt class, but if it's a linkedList starting at the least significant digit, you should be able to do it change your loop to this:
int carryover = 0;
while (a.head != null & b.head != null) {
int sumDigits = Integer.parseInt(a.head.getItem()) + Integer.parseInt(b.head.getItem())+carryover;
// add least significant digit of sumDigits
sum.addToLinkList(Integer.toString(sumDigits % 10), 0);
// remove least significant digit from sumDigit to get the new carryover
carryover = sumDigits / 10;
a.head = a.head.getLink();
b.head = b.head.getLink();
}
if (carryover != 0) {
// if the last carryover isn't 0 add it as most significant digit of the result
sum.addToLinkList(Integer.toString(carryover), 0);
}
but in case you still want to convert between String and int as often as your code does, you need to add the carryover before converting to String[], not after converting:
while (a.head != null & b.head != null) {
// add carryover here
String[] carryCheck = (Integer.valueOf(a.head.getItem()) + Integer.valueOf(b.head.getItem()+carryover) + "").split("");
if (carryCheck.length == 2) {
// don't add carryover here
sum.addToLinkList((Integer.valueOf(carryCheck[1]))+"", 0);
carryover = Integer.valueOf(carryCheck[0]);
} else {
//...
}
// TODO: add carryover as most significant digit, if != 0
Related
I made an RSA Encrypt/Decrypt GUI program with JavaFX.
It seems works well with generating Public and Private keys, but somehow Decryption does not return the plain text I encrypted.
I dunno why this happens, maybe I am misunderstanding the RSA algorithm, so please find ANY problems my code has.
The text file Pnumlist contains the list of Prime numbers I copied from Wikipedia.
I set Private key as n, e and Public key as n, d.
As I know if we set Plain text as M and Crypted text as C, (integer).
C = M^e (mod n)
M = C^d (mod n)
Am I right?
public class Main extends Application {
static int[] arr = new int[120000];
private static int n;
private static int e;
private static int d;
private static int C;
private static int M;
private static int n1;
private static int n2;
private static void SWAPint(int a, int b) {
if(a < b) {
int tmp = a;
a = b;
b = tmp;
}
}
private static int getd() {
int D;
for(D = 1; D < n-1; D++) {
if((e * D) % (n - 1) == 1) {
break;
}
}
return D;
}
private static int GCDr(int a, int b) {
if(b == 0) {
return a;
} else {
return GCDr(b, a%b);
}
}
private static int getCoprime(int E) {
int j;
for(j = 2; j < E; j++) {
if(GCDr(E, j) == 1) {
break;
}
}
return j;
}
private static void keymaker() {
File f = new File("Pnumlist.txt");
try {
Scanner scan = new Scanner(f);
int i = 0;
while(scan.hasNext()) {
arr[i] = scan.nextInt();
i++;
}
int Pnum[] = new int[i];
for(int j = 0; j < Pnum.length; j++) {
Pnum[j] = arr[j];
}
Random slct = new Random();
n1 = Pnum[slct.nextInt(Pnum.length)];
n2 = Pnum[slct.nextInt(Pnum.length)];
SWAPint(n1, n2);
n = n1 * n2;
int Onum = (n1 - 1) * (n2 - 1);
e = getCoprime(Onum);
d = getd();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
#Override
public void start(Stage primaryStage) {
try {
// some javafx stuff...
Encrypt.setOnAction(rct -> {
String tmpP = Ptext.getText();
console.appendText("Input Integer: " + tmpP + "\n");
console.appendText("--------Process--------" + "\n");
M = Integer.parseInt(tmpP);
keymaker();
console.appendText("generated primes: " + n1 + ", " + n2 + "\n");
console.appendText("Calculated key n: " + n + "\n");
console.appendText("Calculated key e: " + e + "\n");
console.appendText("Calculated key d: " + d + "\n");
C = (int) Math.pow(M, e) % n;
console.appendText("--------Crypted Integer--------" + "\n");
console.appendText(Integer.toString(C));
});
Decrypt.setOnAction(rct -> {
String tmpP = Ctext.getText();
console.appendText("\n\nInput Integer: " + tmpP + "\n");
console.appendText("--------Process--------" + "\n");
console.appendText("--------Decrypted Integer--------" + "\n");
int cusM = (int) Math.pow(C, d) % n;
console.appendText(Integer.toString(cusM));
});
// some more javafx stuff...
} catch(Exception e) {
e.printStackTrace();
}
}
// some other javafx methods...
}
I am using Comb Sort to sort out a given array of Strings. The code is :-
public static int combSort(String[] input_array) {
int gap = input_array.length;
double shrink = 1.3;
int numbOfComparisons = 0;
boolean swapped=true;
//while(!swapped && gap>1){
System.out.println();
while(!(swapped && gap==1)){
gap = (int)(gap/shrink);
if(gap<1){
gap=1;
}
int i = 0;
swapped = false;
String temp = "";
while((i+gap) < input_array.length){
numbOfComparisons++;
if(Compare(input_array[i], input_array[i+gap]) == 1){
temp = input_array[i];
input_array[i] = input_array[i+gap];
input_array[i+gap] = temp;
swapped = true;
System.out.println("gap: " + gap + " i: " + i);
ArrayUtilities.printArray(input_array);
}
i++;
}
}
ArrayUtilities.printArray(input_array);
return numbOfComparisons;
}
The problem is that while it sorts many arrays , it gets stuck in an infinite loop for some arrays, particularly small arrays. Compare(input_array[i], input_array[i+gap]) is a small method that returns 1 if s1>s2, returns -1 if s1
try this version. The string array is changed to integer array (I guess you can change it back to string version). The constant 1.3 is replaced with 1.247330950103979.
public class CombSort
{
private static final int PROBLEM_SIZE = 5;
static int[] in = new int[PROBLEM_SIZE];
public static void printArr()
{
for(int i=0;i<in.length;i++)
{
System.out.print(in[i] + "\t");
}
System.out.println();
}
public static void combSort()
{
int swap, i, gap=PROBLEM_SIZE;
boolean swapped = false;
printArr();
while ((gap > 1) || swapped)
{
if (gap > 1)
{
gap = (int)( gap / 1.247330950103979);
}
swapped = false;
for (i = 0; gap + i < PROBLEM_SIZE; ++i)
{
if (in[i] - in[i + gap] > 0)
{
swap = in[i];
in[i] = in[i + gap];
in[i + gap] = swap;
swapped = true;
}
}
}
printArr();
}
public static void main(String[] args)
{
for(int i=0;i<in.length;i++)
{
in[i] = (int) (Math.random()*PROBLEM_SIZE);
}
combSort();
}
}
Please find below implementation for comb sort in java.
public static void combSort(int[] elements) {
float shrinkFactor = 1.3f;
int postion = (int) (elements.length/shrinkFactor);
do {
int cursor = postion;
for(int i=0;cursor<elements.length;i++,cursor++) {
if(elements[i]>elements[cursor]) {
int temp = elements[cursor];
elements[cursor] = elements[i];
elements[i] = temp;
}
}
postion = (int) (postion/shrinkFactor);
}while(postion>=1);
}
Please review and let me know your's feedback.
I'm working on a method, that takes steps between 3 and -3. My program will not print out the steps in a numerical order, and I can't quite figure out how to do it, and I can't find anything elsewhere.
public static final int SENTINEL = Math.abs(3);
public static void randomWalk(Random rand) {
int walk = 0;
while (walk != SENTINEL) {
walk = (rand.nextInt((3 - (-3)) + 1) - 3);
System.out.println("Position = " + walk);
}
}
If that is what you are looking for :
int walk = 0;
int randomStep = 0;
Random rand = new Random();
while (Math.abs(walk) != 3) {
randomStep = rand.nextInt(2) > 0 ? 1 : -1; // -1 or 1 with 50% probability
walk += randomStep;
System.out.print(walk + " ");
}
//sample output: -1 -2 -1 0 1 2 1 2 3
public static void randomWalk(Random rand) {
int walk = 0;
while (walk != SENTINEL) {
walk += rand.nextInt(3) - 1;
if(walk>3) walk = 3;
if(walk<-3) walk = -3;
System.out.println("Position = " + walk);
}
}
I guess you want this.
while (walk != SENTINEL) {
int walk = 0;
walk = (rand.nextInt((3 - (-3)) + 1) - 3);
System.out.println("Walk is = " + walk);
int temp = walk;
if (walk >= -3) {
System.out.println("Wlak plus = " + (temp + 1));
System.out.println("Wlak minus =" + (temp - 1));
}
}
Could this be what you are looking for?
package com.stackoverflow.random;
import java.util.Random;
public class Walking {
private final int bounds;
public Walking(int bounds) {
this.bounds = bounds;
}
private boolean isWithinBounds(int walk) {
return Math.abs(walk) < bounds;
}
public String randomWalk() {
int walk = 0;
StringBuilder sb = new StringBuilder();
while(isWithinBounds(walk)) {
sb.append(walk);
walk = getNextStep(walk);
}
return sb.toString();
}
private Random random = null;
private int getNextStep(int walk) {
if (random == null)
random = new Random();
boolean increase = random.nextBoolean();
return increase?++walk:--walk;
}
public static void main(String[] args) {
Walking app = new Walking(3);
System.out.println("walking: " + app.randomWalk());
}
}
I have written a program to solve Diophantine equations in the form
A5 + B5 + C5 + D5 + E5 = 0;
It should run in N3long(N) time, but it usually takes about 10 minutes for an input size of 100. Can anyone tell me whats wrong?
public class EquationSolver {
//Solves Equations of type: A^5 + B^5 + C^5 + D^5 + E^5 = F^5
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a max value: ");
int N = input.nextInt();
long START_TIME = System.nanoTime();
SLinkedList test = new SLinkedList();
SLinkedList test2 = new SLinkedList();
test = setupLeftList(N);
test2 = setupRightList(N);
System.out.println("Note: This program takes about 7 minutes to complete for input of 100");
test = mergeSort(test);
test2 = mergeSort(test2);
long END_TIME2 = System.nanoTime() - START_TIME;
System.out.println("Total Time:" + END_TIME2/1000000000.0);
checkEquality(test, test2);
long END_TIME3 = System.nanoTime() - START_TIME;
System.out.println("Total Time:" + END_TIME3/1000000000.0);
}
public static SLinkedList setupLeftList(long boundary)
{
//Creates and returns an linkedList of all possible A,B,C values and their sums
SLinkedList leftSums = new SLinkedList();
for(long c = 0; c < boundary; c++)
{
for(long b = 0; b < c; b++)
{
for(long a = 0; a < b; a++)
{
long sum = (long)(Math.pow(a+1,5)) + (long)(Math.pow(b+1, 5)) + (int)(Math.pow(c+1, 5));
Node current = new Node (sum, a+1, b+1, c+1, null);
//System.out.println(sum);
leftSums.addLast(current);
}
}
}
return leftSums;
}
public static SLinkedList setupRightList(long boundary)
{
//Creates and returns an linkedList of all possible D,E,F values and their sums
SLinkedList rightSums = new SLinkedList();
for(int f = 0; f < boundary; f++)
{
for(int e = 0; e < f; e++)
{
for(int d = 0; d < e; d++)
{
long sum = (long)(Math.pow(f+1, 5)) - ((long)(Math.pow(d+1, 5)) + (long)(Math.pow(e+1,5)));
Node current = new Node (sum, d+1, e+1, f+1, null);
//System.out.println(current.getSum());
rightSums.addLast(current);
}
}
}
return rightSums;
}
public static SLinkedList mergeSort(SLinkedList sums)
// Sorts each list by the value of the sum
{
if (sums.length() > 1 )
{
SLinkedList[] splitList = split(sums);
SLinkedList s1 = mergeSort(splitList[0]);
SLinkedList s2 = mergeSort(splitList[1]);
sums = merge(s1, s2);
}
return sums;
}
public static SLinkedList[] split(SLinkedList sums)
{
// Splits a linked list into two (somewhat) equal halves
long midpoint = sums.length()/2;
Node midPoint = sums.elementAt(midpoint);
SLinkedList s1 = new SLinkedList(sums.head, midPoint, midpoint);
SLinkedList s2 = new SLinkedList(midPoint, sums.tail, midpoint);
SLinkedList[] both = new SLinkedList[]{s1, s2};
return both;
}
public static SLinkedList merge(SLinkedList s1, SLinkedList s2)
{
// Merges two sorted lists of elements
SLinkedList sMerged = new SLinkedList();
while(!s1.isEmpty() && !s2.isEmpty())
{
if (s1.getFirst().getSum() < s2.getFirst().getSum())
{
sMerged.addLast(s1.removeFirst());
}
else
{
sMerged.addLast(s2.removeFirst());
}
}
while(!s1.isEmpty())
{
sMerged.addLast(s1.removeFirst());
}
while(!s2.isEmpty())
{
sMerged.addLast(s2.removeFirst());
}
return sMerged;
}
public static void checkEquality(SLinkedList left, SLinkedList right)
{
// Checks two linked lists for nodes that contain the same Sum value
boolean ans = false;
while (left.isEmpty() == false && right.isEmpty() == false)
{
long currentLeft = left.getFirst().getSum();
long currentRight = right.getFirst().getSum();
if (currentLeft > currentRight)
{
right.removeFirst();
}
else if(currentLeft < currentRight)
{
left.removeFirst();
}
else
{
if (left.getFirst().getC() <= right.getFirst().getA())
{
System.out.println("Answer Found: " + "A: " + left.getFirst().getA() + " B: " + left.getFirst().getB() + " C: "
+ left.getFirst().getC() + " D: " + right.getFirst().getA() + " E: " + right.getFirst().getB() + " F: " + right.getFirst().getC());
ans = true;
}
Node temp = left.getFirst().getNext();
while (temp.getSum() == currentRight)
{
if (temp.getC() <= right.getFirst().getA())
{
System.out.println("Answer Found: " + "A: " + left.getFirst().getA() + " B: " + left.getFirst().getB() + " C: "
+ left.getFirst().getC() + " D: " + right.getFirst().getA() + " E: " + right.getFirst().getB() + " F: " + right.getFirst().getC());
ans = true;
}
temp = temp.getNext();
}
right.removeFirst();
left.removeFirst();
}
}
if (ans == false)
{
System.out.println("No answer found.");
}
}
}
The definitive answer is: use a profiler and see what causes a bottleneck...
But I see you have Math.pow() calls, all with longs, and their 5th power.
You could do it quicker, while even detecting the overflow:
public static long pow5(long base) {
if(base <=6208 && base >=-6208) {
return base*base*base*base*base;
} else {
throw new IllegalArgumentException("Overflow!");
}
}
(Magic number disclaimer: 62085 is ~263, is a number is bigger than that, the 5th power won't fit into 64 bits...)
Math.pow uses doubles, which means a lot of conversion in itself...
Also, #Floris pointed out that it is not even worth computing this over and over again - it could be put into a nice array, and just index that
public static long[] pow5 = getPow5(100);
public static long[] getPow5(long numElements) {
long[] toReturn = new long[numElements];
for(long i=0;long<numElements;long++) {
toReturn[i] = i*i*i*i*i;
}
return toReturn;
}
And where needed, instead of Math.pow(x, 5) just use pow5[x]
I am trying to make a calculator that performs the quadratic formula.
Currently if my result would be a decimal it returns NaN. (EDIT: Resolved)
Preferably I would like the result to be in an simplified radical form (i.e. √(99) = 3√(11) ).
How would I go about achieving this?
This is what I have so far.
// Do the math
private double mathCalcPlus(double varA,double varB,double varC) {
return ((-varB + Math.sqrt(varB * varB - 4 * varA * varC)) / 2 * varA);
}
private double mathCalcMinus(double varA,double varB,double varC) {
return ((-varB - Math.sqrt(varB * varB - 4 * varA * varC)) / 2 * varA);
}
Any help will be greatly appreciated.
This works great! However, I decided to add the top bar of the radical sign just for fun :D
import java.util.Scanner;
public class Radical {
public static void main(String[] args) {
System.out.print("Enter the unsimplified radical: ");
Scanner scan = new Scanner(System.in);
int input = scan.nextInt();
recurse(input);
}
public static void recurse(int x) {
System.out.println(" ______");
System.out.println("Attempting to simplify -/" + x);
int a = 0;
int b = 0;
int count = 0;
for (int i = 1; i < x; i++) {
if ((i * (x/i)) == x) {
//System.out.println(i + "<i rest>" + (x/i));
a = i;
b = x/i;
if (Math.sqrt(a)%1==0) {
if (a != 1) {
System.out.println(" ______");
System.out.println(" " + (int)Math.sqrt(a) + "-/" + b);
count = 1;
}
}
}
}
if (count>0) {
recurse(b);
} else if (count==0) {
System.out.println(" ______");
System.out.println("Cannot simplify -/" + x);
}
}
}
Here's something that might help as far as simplifying radicals go. Give it the unsimplified radical (let's say 850) and it should return the correct answer (5-/34). It also tries to recursively simplify what's left in the radical in case it needs to be broken down again.
This was written quickly so I'm sure there are edge cases I missed that will throw off the calculations but I hope it helps at least a little. Best of luck!
import java.util.Scanner;
public class Radical {
public static void main(String[] args) {
System.out.print("Enter the unsimplified radical: ");
Scanner scan = new Scanner(System.in);
int input = scan.nextInt();
recurse(input);
}
public static void recurse(int x) {
System.out.println("Attempting to simplify -/" + x);
int a = 0;
int b = 0;
int count = 0;
for (int i = 1; i < x; i++) {
if ((i * (x/i)) == x) {
//System.out.println(i + "<i rest>" + (x/i));
a = i;
b = x/i;
if (Math.sqrt(a)%1==0) {
if (a != 1) {
System.out.println((int)Math.sqrt(a) + "-/" + b);
count = 1;
}
}
}
}
if (count>0) {
recurse(b);
} else if (count==0) {
System.out.println("Cannot simplify -/" + x);
}
}
}