I have a file (Multiply.txt) that contains comma-separated pairs of integers, one pair per line. I want to multiply the second element of each pair by the least power of 2 necessary to yield a result greater than or equal to the first element of the pair, and print each result. For example, given a line containing "13,8", I want to multiply 8 by 21 to yield 16, and print that.
Given this input file
13,8
17,16
My program prints this output:
0
16
0
32
Instead, I expect
16
32
How can I avoid printing the two zeroes? Here's my program:
/* Sample code to read in test cases:*/
import java.io.*;
public class Multiples_of_a_Number {
public static void main (String[] args) throws IOException {
File file = new File("multiple.txt");
BufferedReader buffer = new BufferedReader(new FileReader(file));
String line;
while ((line = buffer.readLine()) != null) {
line = line.trim();
String[] power = line.split(",");
int[] myPower = new int[power.length];
for (int i = 0; i < power.length; i++) {
String numberAsString = power[i];
myPower[i] = Integer.parseInt(numberAsString);
System.out.println(Multiply(myPower));
}
}
}
public static int Multiply(int[] n){
int t= 0;
for (int i = 0; i < n.length; i++) {
if(n[1] <= n[0]){
t = n[1] * 2;
}else {
}
}
/*while (n.length < n.length-1) {
t = (int) Math.pow(n.length, 2);
}*/
return t;
}
}
If the only thing you want to do is not display zeroes, then just only display when it's not zero:
System.out.println(Multiply(myPower));
with
int result = Multiply(myPower);
if (result > 0) //or != if you work with negatives
{
System.out.println(result);
}
Though I'd personally highly recommend reviewing your code.
You have at least three flaws in your program:
The inner loop in method main() is inappropriate. You don't (seem to) want to process each number individually; rather, you want to process the second element of the pair in light of the first, one time. You are getting four lines of output instead of two because of this problem.
Method Multiply() does not account for the possibility that the second number is already greater than the first (i.e. the case in which you must multiply by 20 == 1). In this case it returns 0. One possible fix would be to initializing local variable t to n[1] instead of to 0.
The implementation of Multiply() seems more broadly to be just wrong, however. It is unclear why you are looping over the elements of n (or at least why you are starting the loop at element 0), and it will not produce a result greater than n[0] if n[1] is less than n[0] / 2. I suspect what you want to do is initialize t to n[1] and then double it as many times as necessary to increase the result above n[0]. That's not at all what you actually are doing.
Related
I want to...
create an asterisk triangle, using Java, that matches the length of whatever number (Between 1-50) the user enters.
Details
The first line would always start with an asterisk.
The next line would increment by one asterisk until it matches the
user's input.
The following lines would then decrement until it is back to one
asterisk.
For instance, if the user was to enter 3, then the output would have one asterisk on the first line, two asterisks on the second line, three asterisks on the third line, and then revert back to two asterisks on the following line before ending with an asterisk on the last line.
What I've tried so far
I am required to use nested for loops. So far, I tried to test it out using this practice example I made below. I was only able to create on output of the numbers. I also have some concepts of outputting asterisk triangles. How can I apply the concept of this code to follow along the user's input number?
import java.util.Scanner;
public class Program
{
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int count, index = 0, value, number;
System.out.println("This program creates a pattern of numbers " );
System.out.println("Based on a number you enter." );
System.out.println("Please enter a positive integer. " );
count = keyboard.nextInt();
value = count;
for (index = 1; index <= count; index++)
{
for (number = value; number >= 1; number--)
{
System.out.println(number);
}
value--;
System.out.println();
}
}
}
Here's how i would proceed
write a method printAsterisks that takes an int N as parameter and writes a line of N asterisks. You wil need a for loop to do so.
call printAsterisks in a for loop that counts from 1 to COUNT
call printAsterisks in a second loop that counts down from COUNT-1 to 1
That should do the trick.
Also, as a side note, you should close your scanner. The easy way to do so is enclose ot in a try-with-resource like so :
try (Scanner keyboard = new Scanner(System.in);) {
// your code here
}
Let us know the version of the program taht works (or the question you still have) :)
HTH
Here is what you want:
public class Asterisk {
private static final String ASTERISK = "*";
private static final String SPACE = "";
private static int LENGTH;
public static void main(String[] args) {
try{
readLength();
for (int i=1; i<=LENGTH; i++) {
if (i == LENGTH) {
for (int j=LENGTH; j>=1; j--) {
drawLine(j);
}
break;
}
drawLine(i);
}
}catch (Exception e) {
System.out.println("You must enter a number between 1 and 50.");
}
}
static void readLength(){
System.out.println("Enter asterisk's length (1-50)");
LENGTH = Integer.parseInt(System.console().readLine());
if (LENGTH<=0 || LENGTH>50)
throw new NumberFormatException();
}
static void drawLine(int asterisks){
StringBuilder line = new StringBuilder();
int spacesLeft = getLeftSpaceCount(asterisks);
int spacesRight = getRightSpaceCount(asterisks);
for (int i=0; i<spacesLeft; i++) {
line.append(SPACE);
}
for (int i=0; i<asterisks; i++) {
line.append(ASTERISK);
}
for (int i=0; i<spacesRight; i++) {
line.append(SPACE);
}
System.out.println(line.toString()+"\n");
}
static int getLeftSpaceCount(int asterisks){
int spaces = LENGTH - asterisks;
int mod = spaces%2;
return spaces/2 + mod;
}
static int getRightSpaceCount(int asterisks){
int spaces = LENGTH - asterisks;
return spaces/2;
}
}
I am required to use nested for loops
Yes, the main logic lies there...
for (int i=1; i<=LENGTH; i++) {
if (i == LENGTH) {
for (int j=LENGTH; j>=1; j--) {
drawLine(j);
}
break;
}
drawLine(i);
}
The triangle using 5 as input.
*
**
***
****
*****
****
***
**
*
Tip:
There is an easier way to get input from the user usingSystem.console().readLine().
In regards to the printing part, I wanted to clean up the answers a little:
int input = 3; //just an example, you can hook in user input I'm sure!
for (int i = 1; i < (input * 2); i++) {
int amount = i > input ? i / 2 : i;
for (int a = 0; a < amount; a++)
System.out.print("*");
}
System.out.println();
}
For our loop conditions, a little explanation:
i < (input * 2): since i starts at 1 we can consider a few cases. If we have an input of 1 we need 1 row. input 2, 3 rows. 4: 5 rows. In short the relation of length to row count is row count = (length * 2) - 1, so I additionally offset by 1 by starting at 1 instead of 0.
i > input ? i / 2 : i: this is called a ternary statement, it's basically an if statement where you can get the value in the form boolean/if ? value_if_true : value_if_false. So if the row count is bigger than your requested length (more than halfway), the length gets divided by 2.
Additionally everything in that loop could be one line:
System.out.println(new String(new char[i > input ? i / 2 : i]).replace('\0', '*'));
And yeah, technically with a IntStream we could make this whole thing a one-line, though at that point I would be breaking out newlines for clarity
Keep in mind, I wouldn't call this the "beginner's solution", but hopefully it can intrigue you into learning about some other helpful little things about programming, for instance why it was I replaced \0 in my one-line example.
recently I met a question like this:
Assume you have an int N, and you also have an int[] and each element in this array can only be used once time. And we need to design an algorithm to get 1 to N by adding those numbers and finally return the least numbers we need to add.
For example:
N = 6, array is [1,3]
1 : we already have.
2 : we need to add it to the array.
3 : we can get it by doing 1 + 2.
4: 1 + 3.
5 : 2 + 3.
6 : 1 + 2 + 3.
So we just need to add 2 to our array and finally we return 1.
I am thinking of solving this by using DFS.
Do you have some better solutions? Thanks!
Here's an explanation for why the solution the OP posted works (the algorithm, briefly, is to traverse the sorted existing elements, keep an accumulating sum of the preceding existing elements and add an element to the array and sum if it does not exist and exceeds the current sum):
The loop tests in order each element that must be formed and sums the preceding elements. It alerts us if there is an element needed that's greater than the current sum. If you think about it, it's really simple! How could we make the element when we've already used all the preceding elements, which is what the sum represents!
In contrast, how do we know that all the intermediate elements will be able to be formed when the sum is larger than the current element? For example, consider n = 7, a = {}:
The function adds {1,2,4...}
So we are up to 4 and we know 1,2,3,4 are covered,
each can be formed from equal or lower numbers in the array.
At any point, m, in the traversal, we know for sure that
X0 + X1 ... + Xm make the largest number we can make, call it Y.
But we also know that we can make 1,2,3...Xm
Therefore, we can make Y-1, Y-2, Y-3...Y-Xm
(In this example: Xm = 4; Y = 1+2+4 = 7; Y-1 = 6; Y-2 = 5)
Q.E.D.
I don't know if this is a good solution or not:
I would create a second array (boolean array) remembering all numbers I can calculate.
Then I would write a method simulating the adding of a number to the array. (In your example the 1, 3 and 2 are added to the array).
The boolean array will be updated to always remember which values (numbers) can be calculated with the added numbers.
After calling the add method on the initial array values, you test for every Number x ( 1 <= x <= N ) if x can be calculated. If not call the add method for x.
since my explanation is no good I will add (untested) Java code:
static int[] arr = {3,5};
static int N = 20;
//An Array remembering which values can be calculated so far
static boolean[] canCalculate = new boolean[N];
//Calculate how many numbers must be added to the array ( Runtime O(N^2) )
public static int method(){
//Preperation (adding every given Number in the array)
for(int i=0; i<arr.length; i++){
addNumber(arr[i]);
}
//The number of elements added to the initial array
int result = 0;
//Adding (and counting) the missing numbers (Runtime O(N^2) )
for(int i=1; i<=N; i++){
if( !canCalculate[i-1] ){
addNumber(i);
result++;
}
}
return result;
}
//This Method is called whenever a new number is added to your array
//runtime O(N)
public static void addNumber( int number ){
System.out.println("Add Number: "+(number));
boolean[] newarray = new boolean[N];
newarray[number-1] = true;
//Test which values can be calculated after adding this number
//And update the array
for(int i=1; i<=N; i++){
if( canCalculate[i-1] ){
newarray[i-1] = true;
if( i + number <= N ){
newarray[i+number-1] = true;
}
}
}
canCalculate = newarray;
}
Edit: Tested the code and changed some errors (but rachel's solution seems to be better anyway)
It is a famous problem from dynamic programming. You can refer to complete solution here https://www.youtube.com/watch?v=s6FhG--P7z0
I just found a possible solution like this
public static int getNum(int n, int[] a) {
ArrayList<Integer> output = new ArrayList<Integer>();
Arrays.sort(a);
int sum = 0;
int i = 0;
while(true) {
if (i >= a.length || a[i] > sum + 1) {
output.add(sum + 1);
sum += sum + 1;
} else {
sum += a[i];
i++;
}
if (sum >= n) {
break;
}
}
return output.size();
};
And I test some cases and it looks correct.
But the one who write this didn't give us any hints and I am really confused with this one. Can anybody come up with some explanations ? Thanks!
I'm not allowed to use methods from any class except String and IO Class
So my code snippet is:
String line = reader.readLine();
while (line != null) {
String[] elements = line.split(",");
// Array could be too big if there are multiple occurances of
// the same number
// Array length + 1 because I can't use the 0 and with a input line of
// 1,2,3 for example would be the length 3 but I would have the
// numbers 0,1,2 in the Array as my index.
String[][] placeholderMatrix = new String[elements.length+1][elements.length+1];
for(int i = 0; i < elements.length-1; i++){
placeholderMatrix[(int)elements[i]][(int)elements[i+1]] = 1;
}
line = reader.readLine();
}
In the File I'm getting are only numbers like that: 1,2,3,4,5,8,7,4
So in my splitted String Array are only Numbers but now if I want to use them as my index for my Matrix(placeholderMatrix)
My problem is in my for loop where I want to use them as my Index I can't use them because it is a String Array. Normally I would use Integer.parseInt but I'm not allowed to :/
Any ideas on how I can implement them as my Index? and any Idea how I can get the perfect length of my Matrix? Because If I get the following numbers: 1,2,2,2,3 My Matrix should only have the numbers:
0 1 2 3
1
2
3
But if I'm using elements.length+1 for the length of my Matrix I would get the numbers 0 1 2 3 4 5
Hope you could understand my problem. Sorry for my bad english and Thanks in advance.
Edit: SO i got another problem with that. If I implement the method(parseInt) of Dici and am using it in the line "placeholderMatrix[parse(elements[i])][parse(elements[i+1])] = 1;" I'm getting the error ArrayOutOfBounce because my defined Array is just the length of my splitted String Array elements. But if I define it with Integer.MAX_VALUE as my length I get a memory error because it is too big. Any ideas?
Edit2: My Task:
I have to take a row of Numbers seperated by ",". (I will split it with the String split method to get only the numbers) Now I have to create a Matrix(2 dimensional Array) and look for the number at the index i of my new String Array and the number at the index i + 1 and have to take the first Number as my column and th second as my row (or vice versa) and implement at that point a 1. Now are my Numbers I will get from 1 to Integer.MAX_VALUE so I would have to create such a big Matrix but this isn't possible because I get the MemoryError.
Error: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at Test.main(Test.java:29)
To understand what I have to do: http://de.wikipedia.org/wiki/Adjazenzmatrix the image at the right but for numbers from to Integer.MAX_VALUE so my 2D Array has to be defined with the length of Integer.MAX_VALUE?
Edit:
So Dici asked for an example:
My Sequence could be: 1,2,5,4
So my Matrix should be:
Hope this is what you wanted Dici
But the numbers I can get from the sequence are 1 to Integer.MAX_VALUE
For converting strings to integers, you can simply implement your own integer parser, it is not complicated. You can start with this and improve it if needed.
public int parseInt(String s) {
int n = 0;
int pow = 1;
for (int i=s.length() - 1 ; i>=0 ; i--) {
String si = String.valueOf(s.charAt(i);
if (si.matches("[0-9]")) {
n += pow*(s.charAt(i) - '0');
pow *= 10;
} else if (si.matches("+|-") && i == 0)
n *= s.charAt(i) == '+' ? 1 : -1;
else
throw new NumberFormatException();
}
return n;
}
Then, I'll handle the second part of your problem. If Integer.MAX_VALuE is one of your input values, you cannot possibly allocate an Integer.MAX_VALUE x Integer.MAX_VALUE matrix. What you need to do is assign contiguous ids to your input values and record the ids in a map so that you can access easily the index of the matrix corresponding to one node value. Here is an example to get you to understand :
public void someMethod() {
int id = 0;
Map<Integer,Integer> idMap = new HashMap<>();
String[] split = reader.readLine().split(",");
int [] nodes = new int[split.length];
for (int i=0 ; i<nodes.length ; i++) {
nodes[i] = parseInt(split[i]);
if (!idMap.containsKey(nodes[i]))
idMap.put(nodes[i],id++);
}
// the map is now constructed, it should probably be stored in an attribute
int[][] placeholderMatrix = new int[nodes.length][nodes.length];
for(int i = 0; i < nodes.length; i++){
if (i > 0) placeholderMatrix[idMap.get(nodes[i])][idMap.get(nodes[i-1])] = 1;
if (i < nodes.length-1) placeholderMatrix[idMap.get(nodes[i])][idMap.get(nodes[i+1])] = 1;
}
}
There are other ways to do it, let me know if this solution is ok
You could do something like:
String keyword = "1,2,3,4,5,8,7,4";//input line from file
String replacedKeyword = keyword.replaceAll("[^\\d]", "");//except numbers replace all. Assuming one digit numbers only.
String[][] placeholderMatrix = new String[replacedKeyword.length()+1][replacedKeyword.length()+1];
char keys[] = replacedKeyword.toCharArray();
for (int i = 0; i<keys.length - 1; i++) {
placeholderMatrix[keys[i] - '0'][keys[i + 1] -'0'] = "1";
}
I couldn't really understand what you want exactly. but, if that going to help a simple method to convert String number to int:
int toInt(String number) {
int num = 0;
for (int i=0; i<number.length(); i++) {
num = num*10 + (number.charAt(i)-'0');
}
return num;
}
alright so im making a program that prints out how many times the numbers 0-9 were input, its supposed to go on forever, until the user types a negative number, then its gonna stop the program and print out the result, heres my code so far:
import java.util.Scanner;
public class opg33 {
public static void main(String args[]) {
System.out.println(1 + ":" + "\t" + "Integer 0-9");
Scanner keyboard = new Scanner(System.in);
int[] a = new int[10];
int counter = 0;
int input;
input = keyboard.nextInt();
boolean exit = true;
while (exit == true) {
counter++;
System.out.println((counter + 1) + ":" + "\t" + "Integer 0-9");
if (input > -1 && input < 10) {
a[input]++;
}
input = keyboard.nextInt();
if (input < 0) {
exit = false;
for (int i = 0; i < a.length; i++) {
System.out.print(i + ":");
for (int n = 0; n < a[i]; n++)
System.out.print("x");
System.out.println();
}
}
}
}
}
as you can see this program works perfectly fine, just as I wanted it to! the only question I have, is, how can I make it print out vertically like a bar graph (columns), instead of horizontally? thanks in advance!
You mean something like...?
1: Integer 0-9
1
2: Integer 0-9
1
3: Integer 0-9
2
4: Integer 0-9
2
5: Integer 0-9
2
6: Integer 0-9
3
7: Integer 0-9
3
8: Integer 0-9
7
9: Integer 0-9
8
10: Integer 0-9
-1
x
x x x
x x x x x
0 1 2 3 4 5 6 7 8 9
The first thing you need to do is determine the max height of the chart...
// Calculate the required height...
/*
All this loop does, is loops through the array "a"
and finds the maximum value contained within,
this is the largest number of times the user
entered that value
The loop itself is just an enhanced "for-next-loop",
that is, it's a short cutted way of saying...
for (int index = 0; index < a.length; index++) {
int value = a[index];
...
}
*/
int maxFrequency = 0;
for (int value : a) {
// This is a really simply way to calculate the max value within
// range, it just says, return me the value which is the larger
// of two...
maxFrequency = Math.max(value, maxFrequency);
}
Next, you need to print each row of the chart, starting at the top and moving to the bottom. For each column, you need to determine if it has a value to be displayed within that row...
// This builds each row
for (int row = maxFrequency; row > 0; row--) {
// This is used instead of String concatenation (String + String)
// This is the preferred mechanism for doing String concatenation
// in loops as it uses less memory and will generally be faster...
StringBuilder sb = new StringBuilder(30);
// We need to inspect each value in the array to determine
// if we need to display something...
// The basic idea is, we will only start displaying "x"
// when the value in the array >= the row number...
for (int value : a) {
// This just appends each column value as
// required, prefixing and suffixing it with spaces
sb.append(" ");
if (value >= row) {
sb.append("x");
} else {
sb.append(" ");
}
sb.append(" ");
}
// Print the row...
System.out.println(sb.toString());
}
And finally, you need to print the footer...
StringBuilder sb = new StringBuilder(30);
for (int i = 0; i < a.length; i++) {
sb.append(" ").
append(i).
append(" ");
}
System.out.println(sb.toString());
The hows and why of StringBuilder
A book could be written on this subject, so the information provided here is just an overview...
StringBuilder should be used, especially, when concatenating Strings in loops, basically because it reduces the number of temporary, short lived objects that are created and makes the process more efficient.
Normally the Java compiler will convert String concatenation to use StringBuilder internally, but because of the nature of loops, can't do so. In your case, it's probably not all that important, but in long running programs which might iterate through the loop, hundreds, thousands or even millions of time, it becomes a performance bottleneck, so it is a good habit to form.
Internally, a StringBuilder is a self managed char array, this is not particular important, but it's nice to know. When you use .append, the StringBuilder is taking the content, making space for it within it's internal buffer and writing out the content to it. It might sound like that's introducing it's own overheads and to a certain extent it is (you can do things to imittergate these), but it's less then having to run a garbage collection cycle...
toString simply then converts the char array to a String object...
You can find more information at The StringBuilder Class
I'm a beginner in programming and I've been doing the Project Euler programming problems to practice, I've been able to make my way so far, but this time I had to ask for help. Without spoilers, the problem I'm trying to solve consists of finding the sum of the digits of a very large number, so I can't hold it in an int or a double. So I made this method to multiply two strings containing a numeric value.
private static String multiply(String a, String b) {
// No, I'm not checking if the strings are numeric
int subTotal = 1, extra = 0;
String waitingString = "";
StringBuilder number1 = new StringBuilder(a);
StringBuilder number2 = new StringBuilder(b);
List<String> numbers = new ArrayList<String>();
// The reason I reverse the numbers is the for() loops
// I don't want to count down through the numbers, that
// would just confuse me more.
number1.reverse();
number2.reverse();
for (int i = 0; i < number1.length(); i++) {
waitingString = "";
subTotal = Character.getNumericValue(number1.charAt(i));
for (int j = 0; j < number2.length(); j++) {
subTotal *= Character.getNumericValue(number2.charAt(j));
subTotal += extra;
char[] temp = String.valueOf(subTotal).toCharArray();
waitingString = temp[temp.length - 1] + waitingString;
if (subTotal >= 10 || ((j == number2.length() - 1) && (String.valueOf(subTotal).length() > 1))) {
extra = Integer.parseInt(String.valueOf(subTotal).substring(0, temp.length - 1));
} else {
extra = 0;
}
subTotal = Character.getNumericValue(number1.charAt(i));
}
for (int k = 0; k < i; k++) {
waitingString += "0";
}
waitingString = extra + "" + waitingString;
numbers.add(waitingString);
}
// sumAll() is not the problem just in case you were wondering.
// Because as you've read the code, I'm passing a List<String>
// to it and as I was trying to find the error I printed the list
// before everything to check the values and the error was already
// there, 3 of the values are wrong.
return sumAll(numbers);
}
When testing I'm multiplying this number by itself: 1125899906842624. The result should be 1267650600228229401496703205376. But I'm getting 1267650600228229401607703205376. That's a difference of 111000000000. I've been trying to find the error for 2 days and i just can't.
I'm not looking for alternative or better ways to do this, I just can't find the error in my code that adds more than it should.
If you need to see the rest of the code I can provide it and please don't mind spelling/grammar errors, english is not my native language.
Without trying to run this or look at it under a debugger: it looks like you're setting up an extra variable which is a carry, i.e. the value which should get added to the next product as you move to the left (in your original numbers, not the reversed ones). One problem I can see is that if the last product in your inner loop produces something greater than or equal to 10, you compute extra; but then when you go the next outer loop, extra still has that value and gets added to subTotal when it shouldn't be. Try adding the statement extra = 0; at the beginning of your outer loop, and before the inner loop starts. That may fix the problem.
P.S. You're making a lot of extra work for yourself by representing the subTotal as a string and working with it. While I understand why you'd want to use strings for the two multiplicands and the product, subTotal is the product of two single digits with a carry added, and it can never be greater than 89. So you should never have to convert it to a string and work with the string. Thus, instead of
char[] temp = String.valueOf(subTotal).toCharArray();
waitingString = temp[temp.length - 1] + waitingString;
you could say
waitingString = String.valueOf(subTotal % 10) + waitingString;
or something similar (subTotal % 10 gives the remainder when subTotal is divided by 10, and is therefore the last digit of subTotal); and instead of the complex code to compute extra, just say
extra = subTotal / 10;
which divides by 10 and throws away the remainder. You shouldn't be computing String.valueOf(subTotal) at all.
PPS. Don't worry about the answers that tell you to use BigInteger. If you were doing a real programming project, that's what you'd use. But for someone learning how to program, I think that writing a program to compute the product of two numbers, the long way, is a good learning tool.
As someone commented, this would probably be a job for the BigInteger class. Just say
BigInteger intA = new BigInteger(a)
BigInteger intB = new BigInteger(b)
and then call
intA.multiply(intB)
and that will get you a BigInteger containing the result.
I would use BigInteger like this
private static String multiply(String a, String b) {
if (a == null || b == null) {
if (b != null) return b;
return a;
}
BigInteger v = new BigInteger(a, 10);
if (v != null) {
BigInteger t = new BigInteger(b, 10);
if (t != null) {
BigInteger r = v.multiply(t);
return r.toString();
}
}
return "";
}
public static void main(String[] args) {
String result = multiply("1125899906842624", "1125899906842624");
String good = "1267650600228229401496703205376";
System.out.println(result.equals(good));
}
Which prints true when I run it.