i am newbie in android developing, i have a simple question.
Imagine I have a long long number, like 166516516516516515.
And i want to have divided output like:
1,6,6,5,1,6,5,1,6,5,1,6,5,1,6,5,...
I mean i want to have every every one in output.
I wrote this algorithm :
int temp = 2536;
ArrayList<Integer> array = new ArrayList<Integer>();
do {
array.add(temp % 10);
temp /= 10;
}
while (temp > 0);
for (int i = 0; i < array.size(); i++) {
Log.i("LOG", "Dynamic Numbers Array Index #" + i + " = " + array.get(i));
}
it works for small numbers (int)
but for long number it doesn't give true work,
How can i solve it to work with big numbers?
thanks.
Just read that stuff into a string and do:
for(char c : str.toCharArray()){}
No need to divide anything and you can have arbitrary length.
If you need ints just convert by doing:
int i = (int)(c - '0');
First of all, you need to watch out if you can "cram" all your number into simple int. Chances are that if it's too long you simply cannot do that at all - as you probably noticed by now.
I took another approach to the solution, but it might not be exactly what you need. Treat the number as a string.
String temp = "166516516516516515";
breakUp(temp);
private static void breakUp(String string){
int length = string.length();
for (int i = 0; i < length; i++) {
String temp = string.substring(i, i+1);
int tempInt = Integer.valueOf(temp);
System.out.print(tempInt + " - "); //or whatever here, you can make function return list instead of void
}
}
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
public class Callone {
public static void main(String[] args)
{
BigInteger i = new BigInteger("166516516516516515");
List<Integer> list = new ArrayList<Integer>();
BigInteger ten = new BigInteger("10");
while (!i.equals(BigInteger.ZERO))
{
list.add(0, i.mod(ten).intValue());
i = i.divide(ten);
}
System.out.println(list.toString());
}
}
output: [1, 6, 6, 5, 1, 6, 5, 1, 6, 5, 1, 6, 5, 1, 6, 5, 1, 5]
split longString to intArray
Split longString to char array and then use Character.digit to get digit value.
public static int[] splitLong(String longStr) {
int i = 0;
int[] nums = new int[longStr.length()];
for (char l : longStr.toCharArray())
nums[i++] = Character.digit(l, 10);
return nums;
}
Other approach:
public static int[] splitLongNum(String longStr) {
int len = longStr.length();
int[] nums = new int[len];
for (int j = 0; j < len; j++)
nums[j] = Character.digit(longStr.charAt(j), 10);
return nums;
}
Related
I need to write a program, which deletes a number of elements from an int array that are equal to some int value. Eventually I should get an array that isn't bigger than the initial one.
I mustn't use lists or any methods that do the deletion directly.
I tried to do this this way and I can't trace the flaw. I suppose, it should be in the last "for" construction but I'm not sure.
import java.util.Arrays;
import java.util.Scanner;
public class App {
public static void main(String\[\] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Array size: ");
int sizeInput = scan.nextInt();
int[] original = new int[sizeInput];
System.out.print("Array itself: ");
for (int i = 0; i < sizeInput; i++) {
original[i] = scan.nextInt();
}
System.out.println("Number to be deleted: ");
int dNumber = scan.nextInt();
int[] newArr = new int[original.length];
for (int i = 0; i < original.length - 1; i++) {
int sum = 0;
if (original[i] == dNumber) {
newArr[i] = original[i + 1];
sum = sum + 1;
} else if (original[i] != dNumber) {
newArr[i] = original[i + sum];
}
}
System.out.println(Arrays.toString(newArr));
}
}
and here's what I got in my console eventually:
Array size: 5
Array itself: 1 2 3 4 5
Number to be deleted: 2
\[1, 3, 3, 4, 0\]
You see? In the output I get the second "3" for some reason and I also don't get why there's no last element of the initial array.
Please, explain what wrote wrong so that my code doesn't solve the problem. And please explain ho can I solve It. Thanks!
You need a position int for the new array, so you go further only when you set a new value
int[] original = {1, 2, 3, 4, 5};
int dNumber = 2;
int[] newArr = new int[original.length];
int j = 0;
for (int val : original) {
if (val != dNumber) {
newArr[j] = val;
j++;
}
}
newArr = Arrays.copyOf(newArr, j); // truncate
System.out.println(Arrays.toString(newArr));
// [1, 3, 4, 5]
here in below program i am defining ArrayList of size 7 [1,2,3,4,5,6,7] and and rotating right by 3 places but when i print the numbers1 list it gives me my expected answer numbers: [5, 6, 7, 1, 2, 3, 4] but when i return this ArrayList and then print it, it gives me this answer numbers: [2, 3, 4, 5, 6, 7, 1] why is that please explain.
package QAIntvSprint;
import java.util.ArrayList;
import java.util.Scanner;
public class RotateArray {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 0; i < n; i++) {
numbers.add(sc.nextInt());
}
rotateArray(numbers, k);
ArrayList<Integer> ans = rotateArray(numbers, k);
for (Integer x : ans) {
System.out.print(x + " ");
}
}
static ArrayList<Integer> rotateArray(ArrayList<Integer> numbers, int k) {
for (int i = 0; i < k; i++) {
numbers.add(0, numbers.get(numbers.size() - 1));
numbers.remove(numbers.size() - 1);
}
ArrayList<Integer> numbers1 = numbers;
System.out.println("numbers: " + numbers1.toString());
return numbers1;
}
}
output
You are running your function twice:
rotateArray(numbers, k); // first
ArrayList<Integer> ans = rotateArray(numbers, k); // second
So the numbers are shifted by 6 instead of 3 positions
Besides, your function does not create a new copy of the array
You return a reference to the same array
ArrayList<Integer> numbers1 = numbers; // copies a reference to an object, not the object itself
return numbers1; // returns the original link
So i suggest refactoring your code like this:
public class RotateArray {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 0; i < n; i++) {
numbers.add(sc.nextInt());
}
// the function will modify the ArrayList by reference, it will change
rotateArray(numbers, k);
for (Integer x : numbers) {
System.out.print(x + " ");
}
}
static void rotateArray(ArrayList<Integer> numbers, int k) {
for (int i = 0; i < k; i++) {
numbers.add(0, numbers.get(numbers.size() - 1));
numbers.remove(numbers.size() - 1);
}
}
}
That's because your function rotateArray changes your numbers ArrayList you give it as parameter. So basically it changes the List (numbers) in your main method. And because you call the method two times, the array gets rotated in sum 6 times (like you see in your final output)
If you don't want to change the ArrayList you give in as a parameter, you should do something like
ArrayList<Integer> newList = new ArrayList(numbers);
as first in you rotateArray method and then rotate this list.
here
ArrayList<Integer> ans = rotateArray(numbers, k);
rotates
numbers, returned by the previous line
Delete
rotateArray(numbers, k);
Currently i started reading a book about alogirthms so I'm now trying some very simple algorithms to get comfortable with converting and so on.. In this small class I want to enable a school adding function with carry.
How can i convert the resulting Int Array into an int? I do not know how to convert them adequate..
The current result is [7, 8, 3, 7, 9, 0, 5, 6] and I want to concat the numbers into one Integer of (78379056). Which possibilities do I have?
public class Addition {
public int[] addiere(int[] a, int[] b) {
int res = 0;
int[] c = new int[a.length];
for(int i = a.length-1 ; i>=0 ; i--) {
res = a[i]+b[i];
if(res>=10) {
c[i] = oneValue(res);
a[i-1]+=1;
} else c[i]=res;
System.out.println("a -- "+a[i]+" b -- "+b[i]+" c -- "+c[i]);
}
return c;
}
public int oneValue(int t) {
String res;
int val;
res=Integer.toString(t);
res = res.substring(res.length()-1);
val = Integer.parseInt(res);
return val;
}
public static void main(String[] args) {
int[] a = {3,4,6,8,9,1,2,4};
int[] b = {4,2,5,7,8,9,3,2};
Addition add = new Addition();
int[] result;
//returns an array of Integers
System.out.println(Arrays.toString(add.addiere(a, b)));
result = add.addiere(a, b);
//HERE should be a method to convert the result ( Array of Integers ) just into a normal integer
}
}
Given the array
int arr[] = { 7, 8, 3, 7, 9, 0, 5, 6 };
you can simply do:
long num = Long.parseLong(Arrays.stream(arr)
.mapToObj(String::valueOf)
.collect(Collectors.joining()));
which outputs
78379056
Explanation:
In the mapToObj(...) we convert each element from an int to
a String using the valueOf method.
Next, we collect each of these individual Strings into one String by
means of Collectors.joining()
Now, we convert this String into a long. You can read up more about
streams from the docs here
We use long here just in case the number is too big to be contained in an int.
You can either convert the array into a String and use Integer.parseInt() to get this result or you use a simple loop adding up the numbers multiplied by 10 with their position exponent:
int r = 0;
for (int i = 0; i < result.length; i++) {
r += result[i] * Math.pow(10, result.length - i - 1);
}
I would prefer this solution.
The result for the array [7, 8, 3, 7, 9, 0, 5, 6] is 78379056.
Beside that you should consider using long instead of int if you have numbers out of the int range (78379056).
Edit: Here is a solution with Integer.parseInt():
StringBuilder builder = new StringBuilder();
for (int i : result) {
builder.append(i);
}
int r = Integer.parseInt(builder.toString());
Alternatively you can take a look at Nicholas K's answer.
public static void main(String[] args) {
int[] a = {7, 8, 3, 7, 9, 0, 5, 6};
int m = 1;
int r = 0;
for (int i=a.length-1; i>=0; i--) {
r = a[i] * m + r;
m = m * 10;
}
System.out.println(r);
}
prints:
78379056
Eventually, you could multiply each number by a power of 10 and add them together. For example this code will return "1234".
int[] array = {1, 2, 3, 4};
int total = 0;
for(int i = 0; i < array.length; i++)
if(array[i] > 9 && array[i] < 0)
throw new IllegalArgumentException("Only use digits");
else
total += array[i] * Math.pow(10, array.length - i - 1);
System.out.println(total);
It works in all cases, except cases with number. Make sure you handle the error.
(be carrefull to Integer.MAX_VALUE)
You can use BigInteger to hold the number which is more than int max size as well as you can avoid NumberFormatException.
public static void main(String[] args) {
int[] ary = {2,1,4,7,4,8,3,6,4,7};
StringBuilder numBuilder = new StringBuilder();
for(int num:ary) {
numBuilder.append(num);
}
BigInteger maxInt = BigInteger.valueOf(Integer.MAX_VALUE);
BigInteger finalNum = new BigInteger(numBuilder.toString());
if(finalNum.compareTo(maxInt)>0) {
//number is more the max size
System.out.println("number is more than int max size");
}else {
int result = finalNum.intValueExact();
System.out.println(result);
}
}
The my goal is to take a user's input and rotate the array however many times based off of their integer input. At first I was trying to get the array to reverse just to see it shift but I have a few errors in my function that won't let me compile.
Edit: I know I used list instead of using arr. I was looking at an example and accidentally typed it in.
Here is my code:
import java.util.Scanner;
public class Project1P2 {
public static void main(String[] args) {
int[] arr1 = {2,4,6,8,10,12};
int[] arr2 = shift(arr1);
Scanner input = new Scanner(System.in);
System.out.print("Here is the Array: " + arr1);
System.out.println("Enter a number to shift array: ");
int n = input.nextInt();
}
public static int[] shift(int[] arr) {
int[] arrShiftDone = new int[list.length];
for (int i = 0, j = arrShiftDone.length - 1; i < list.length; i++, j--) {
arrShiftDone[j] = list[i];
}
return arrShiftDone;
}
}
You need to fix a couple of things:
shift method never gets called from the main method, which means it won't do anything to the array
shift method should have another argument for the number of places to shift, say n
In shift method, you are using list whereas the argument is declared as arr
Below is an example method that shifts the array:
public static int[] shift(int[] arr, int n) {
if(n > arr.length)
n = n%arr.length;
int[] result = new int[arr.length];
for(int i=0; i < n; i++){
result[i] = arr[arr.length-n+i];
}
int j=0;
for(int i=n; i<arr.length; i++){
result[i] = arr[j];
j++;
}
return result;
}
The compilation error is because the variable list is unknown. Should be using the argument arr instead of list inside the method shift(int[] arr).
You can use Arrays.stream(int[],int,int) method twice to get two streams with the specified ranges of the array: near and far, then swap them and concat back into one stream, and thus get a shifted array:
public static int[] shiftArray(int[] arr, int n) {
return IntStream
.concat(Arrays.stream(arr, n, arr.length),
Arrays.stream(arr, 0, n))
.toArray();
}
public static void main(String[] args) {
int[] arr1 = {2, 4, 6, 8, 10, 12};
System.out.println("Source array: " + Arrays.toString(arr1));
System.out.println("Enter a number: ");
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int[] arr2 = shiftArray(arr1, n % arr1.length);
System.out.println("Shifted array: " + Arrays.toString(arr2));
}
Output:
Source array: [2, 4, 6, 8, 10, 12]
Enter a number:
3
Shifted array: [8, 10, 12, 2, 4, 6]
See also: Place positive numbers before negative
Your mistake is that in your shift method you are using list, it should be arr. I have updated it below. I have also included the shift method.
Edited to include negative shifts.
public static void main(String[] args) {
int[] arr1 = {2, 4, 6, 8, 10, 12};
int[] arr2 = reverseArray(arr1);
Scanner input = new Scanner(System.in);
System.out.println("Here is the Array: " + Arrays.toString(arr1));
System.out.print("Enter a number to shift array: ");
int n = input.nextInt();
int[] arr3 = shiftArray(arr1, n);
System.out.println("Here is the shifted Array: " + Arrays.toString(arr3));
}
public static int[] reverseArray(int[] arr) {
int[] arrShiftDone = new int[arr.length];
for (int i = 0, j = arrShiftDone.length - 1; i < arr.length; i++, j--) {
arrShiftDone[j] = arr[i];
}
return arrShiftDone;
}
public static int[] shiftArray(int[] arr, int shift) {
int[] arrShiftDone = new int[arr.length];
shift = shift % arr.length;
if (shift < 0) {
shift = arr.length + shift;
}
for (int i = 0 + shift, j = 0; j < arr.length; i++, j++) {
if (i >= arr.length) {
arrShiftDone[j] = arr[i - arr.length];
} else {
arrShiftDone[j] = arr[i];
}
}
return arrShiftDone;
}
I'm currently working on a problem that asks me to find the millionth lexicographic permutation of 0,1,2,3,4,5,6,7,8,9. I thought of a very crude solution at first glance that had a complexity of around O(n^3)
public static String permute(char[] a){
ArrayList<String> array = new ArrayList<String>();
int counter = 1;
for (int i = 0; i < a.length; i++){
array[counter] += a[i];
for (int j = 0; j < i; j++){
array[counter] += a[j];
for(int k = a.length; k > i; k--){
array[counter] += a[k];}counter++;}
}
}
The code may not be perfect but the idea is that a single digit is selected and then moves to the end of an array. The second array creates the numbers behind the selected digit and the third array creates numbers after it. This seems like a terrible algorithm and i remembered a past algorithm that's like this.
public static HashSet<String> Permute(String toPermute) {
HashSet<String> set = new HashSet<String>();
if (toPermute.length() <= 1 )
set.add(toPermute);
else {
for (int i = 0; i < toPermute.length(); i++ )
for (String s: Permute(toPermute.substring(0,i)+ toPermute.substring(i+1)))
{
set.add(toPermute.substring(i,i+1)+s);}
}
return set;
}
}
The problem is that this algorithm uses unordered sets and I have no idea about how it can become ordered enough for me to find the millionth permutation. I also do not know the complexity other than the fact it could be O(n^2) because it calls itself n times and then unstacks.
A couple of things in general about your code above:
You should implement to interfaces and not concrete classes I.e. List<String> array = .... Similarly with your Set.
Array's start at index 0, you are starting your counter at index 1.
Finally to answer your question there is a brute force way and a more elegant way that uses some principles in math. Have a look at this site which explains the approaches.
It seems to me (1) which permutation is the millionth depends absolutely on the order you use, and (2) permutations of this sort are ripe problems for recursion. I would write this as a recursive program and increment the count for each iteration. [was that your question? I didn't really see a question...]
Here is a solution that is more efficient:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class P24 {
static final int digits[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
static List<Integer> remainedDigits = new ArrayList(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
static final int factorials[] = new int[digits.length + 1];
static final int N = 1000_000;
static int low = -1;
static int lowIndex = -1;
static int highIndex = -1;
public static void main(String args[]) {
populateFactorials(digits.length);
validateN(N);
identifyMargins();
int n = N; // it will be changed
int fixedDigits = digits.length - highIndex;
String result = "";
for (int i = 0; i < fixedDigits; i++) {
result += remainedDigits.get(0);
remainedDigits.remove(0);
}
for (int i = fixedDigits; i < digits.length; i++) {
int pos = 0;
int firstDigit = remainedDigits.get(pos);
low = factorials[lowIndex];
while (n - low > 0) {
pos++;
n -= low;
}
lowIndex--;
result += remainedDigits.get(pos);
remainedDigits.remove(pos);
}
System.out.println(result);
}
private static void validateN(int n) {
if (n < 0 || n > factorials[factorials.length - 1]) {
System.out.println("The input number is not valid");
System.exit(0);
}
}
private static void identifyMargins() {
for (int i = 0; i < factorials.length - 1; i++) {
if (factorials[i] <= N && N < factorials[i + 1]) {
lowIndex = i;
highIndex = i + 1;
}
}
}
private static void populateFactorials(int max) {
for (int i = 0; i <= max; i++) {
factorials[i] = fact(i);
}
}
private static int fact(int x) {
if (x == 0 || x == 1) {
return 1;
}
int p = 1;
for (int i = 2; i <= x; i++) {
p *= i;
}
return p;
}
}
Time: 305 microseconds.
Explanation:
Because the total number of permutations for {a1, ..., an} is n!, I decided that I need a factorials array. I stored in it: {0!, ..., 10!}.
I identified where is the number placed in this sequence, and for our case (N = 1000000) it is between 9! and 10!. If it was lower than 9! I add a padding of fixedDigits digits taken from the remainedDigits array.
Because the number is bigger than 9!, I count how many times I can extract 9! from the number and the result helps me to obtain the first digit. Then, I have a similar approach for 8!, 7!, etc.
The above explanation is based on the following simple observation. If we have a set {a1,...,ai,...,an} and we fix a1, ..., ai, we can obtain (n-i)! different strings.
Notice that if you use:
static List<Integer> remainedDigits = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
you cannot remove elements from the list.
`