How to loop inside array? - java

[ASK]
How to loop inside array? this is right?
weather_data = new Weather[]
{
for (i= 0; i < listOfMenu.size(); i++) {
new Weather(R.drawable.dring1, listOfMenu.get(0)),
}
};

String[] elements = { "a", "a", "a", "a" };
for( int i = 0; i < elements.length - 1; i++)
{
String element = elements[i];
String nextElement = elements[i+1];
}

Short answer, you can't.
Long answer is that it isn't apart of the Java syntax. You have the code to loop through it right there, all you have to do is move it outside. Check out this handy snippet:
Weather[] weather_data = new Weather[listOfMenu.size()];
for (i= 0; i <= listOfMenu.size()-1; i++) {
weather_data[i] = new Weather(R.drawable.dring1, listOfMenu.get(i));
}

It's simple, let me show you.
To enter inside a array and go around with this array you use a simple for, as you did:
for ( parameter : arrayName)
instruction
If by example you want to print the values that are inside the array, you should do like this:
int[] arrayNum = {87, 68, 52, 5, 49, 83, 45, 12, 64}; /
for(int i : arrayNum)
System.out.printf("Array Elements" + arrayNum[i]);
}
I didn't quite understand what you are trying to do, but my answer was a direct response to your question.

Related

Integers in array Java

I have an array that contains [45,8,50,15,65,109,2]. i would like to check to see if the zero element of my array is greater than my first element.
if ( 45 > 8)
then i would like to add 45 to brand new sub array.
i would like to continue checking my array for anything that is bigger than 45 and add it to the new sub array.
The new sub array has to keep the numbers added in the way they where added.The result should be [45,50,65,109]
I thought by creating this was going in the right direction but im doing something wrong so please help.
int[] x = [45,8,50,15,65,109,2];
int[] sub = null;
for(int i = 0; i > x.length; i++) {
for(int k = 0; k > x.length; k++) {
if(x[i] > x[k]){
sub = i;
First thing first. Your question contains some errors.
you should write int[] x = {45,8,50,15,65,109,2}; instead of int[] x = [45,8,50,15,65,109,2]; You can not use [] to initialize array!
What does it mean for(int i = 0; i > x.length; i++). Your program must not run! Because, the value of i is less than x.langth. First condition check is false, so loop will not works!
Same for for(int k = 0; k > x.length; k++)
How do you want to store value in an array without index? You have to write sub[i] = x[i]; here, i means what index value you want to store where!
Finally, do you want to do sorting? If yes, then you need another variable named temp means temporary!
Try to clear the basic and after then try this code.Sorting Link
Best of Luck!
It is possible to filter the input array using Java 8 Stream API:
int[] x = {45, 8, 50, 15, 65, 109, 2};
int[] sub = Arrays.stream(x)
.filter(n -> n >= x[0])
.toArray();
System.out.println(Arrays.toString(sub));
Output:
[45, 50, 65, 109]
If you're trying to fetch everything greater than 0th element.
Use the following:
Plain old java code:
int[] x = {45,8,50,15,65,109,2};
int[] sub = new int[x.length];
int first = x[0];
sub[0]=first;
int index=1;
for(int i = 1; i < x.length; i++) {
if(x[i] > first){
sub[index]=x[i];
index++;
}}
Streams API:
int[] x = {45, 8, 50, 15, 65, 109, 2};
int[] sub = Arrays.stream(x).filter(number -> number>=
x[0]).toArray();
where stream() is converting array to a stream, filter is applying the required condition and then ending it with conversion into an Array again.

How to store this pattern in Java arraylist?

I want to store the below array pattern in List, I am not understanding how to implement this as it has alternate increment.
Increment the number by 399.
Increment by 1
and continue the above 2 steps for a certain length of numbers.
If someone can guide me for the logic with simple OOPs concepts
0, 400, 401, 800, 801, 1200, 1201, 1600, 1601, 2000
You could also do something like this:
//add the first item outside of the loop, so that you can access the previous item within it
list.add(1)
//loop through the list in increments of 2
for (int i = 1; i < length; i += 2) {
list.add(list.get(i - 1) + 399);
list.add(list.get(i) + 1);
}
Figured it out, this is what I wrote now, and it workds
int pages = 8;
List<Integer> numArray = new ArrayList<Integer>();
numArray.add(0);
boolean incrementFlag = false;
int i = 400;
for (int j = 0; j < (pages-1); j++) {
numArray.add(i);
if (incrementFlag)
i += 399;
else
i += 1;
incrementFlag = !incrementFlag;
}

char array to int array

I'm trying to convert a string to an array of integers so I could then perform math operations on them. I'm having trouble with the following bit of code:
String raw = "1233983543587325318";
char[] list = new char[raw.length()];
list = raw.toCharArray();
int[] num = new int[raw.length()];
for (int i = 0; i < raw.length(); i++){
num[i] = (int[])list[i];
}
System.out.println(num);
This is giving me an "inconvertible types" error, required: int[] found: char
I have also tried some other ways like Character.getNumericValue and just assigning it directly, without any modification. In those situations, it always outputs the same garbage "[I#41ed8741", no matter what method of conversion I use or (!) what the value of the string actually is. Does it have something to do with unicode conversion?
There are a number of issues with your solution. The first is the loop condition i > raw.length() is wrong - your loops is never executed - thecondition should be i < raw.length()
The second is the cast. You're attempting to cast to an integer array. In fact since the result is a char you don't have to cast to an int - a conversion will be done automatically. But the converted number isn't what you think it is. It's not the integer value you expect it to be but is in fact the ASCII value of the char. So you need to subtract the ASCII value of zero to get the integer value you're expecting.
The third is how you're trying to print the resultant integer array. You need to loop through each element of the array and print it out.
String raw = "1233983543587325318";
int[] num = new int[raw.length()];
for (int i = 0; i < raw.length(); i++){
num[i] = raw.charAt(i) - '0';
}
for (int i : num) {
System.out.println(i);
}
Two ways in Java 8:
String raw = "1233983543587325318";
final int[] ints1 = raw.chars()
.map(x -> x - '0')
.toArray();
System.out.println(Arrays.toString(ints1));
final int[] ints2 = Stream.of(raw.split(""))
.mapToInt(Integer::parseInt)
.toArray();
System.out.println(Arrays.toString(ints2));
The second solution is probably quite inefficient as it uses a regular expression and creates string instances for every digit.
Everyone have correctly identified the invalid cast in your code. You do not need that cast at all: Java will convert char to int implicitly:
String raw = "1233983543587325318";
char[] list = raw.toCharArray();
int[] num = new int[raw.length()];
for (int i = 0; i < raw.length(); i++) {
num[i] = Character.digit(list[i], 10);
}
System.out.println(Arrays.toString(num));
You shouldn't be casting each element to an integer array int[] but to an integer int:
for (int i = 0; i > raw.length(); i++)
{
num[i] = (int)list[i];
}
System.out.println(num);
this line:
num[i] = (int[])list[i];
should be:
num[i] = (int)list[i];
You can't cast list[i] to int[], but to int. Each index of the array is just an int, not an array of ints.
So it should be just
num[i] = (int)list[i];
For future references. char to int conversion is not implicitly, even with cast. You have to do something like that:
String raw = "1233983543587325318";
char[] list = raw.toCharArray();
int[] num = new int[list.length];
for (int i = 0; i < list.length; i++){
num[i] = list[i] - '0';
}
System.out.println(Arrays.toString(num));
This class here: http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html should hep you out. It can parse the integers from a string. It would be a bit easier than using arrays.
Everyone is right about the conversion problem. It looks like you actually tried a correct version but the output was garbeled. This is because system.out.println(num) doesn't do what you want it to in this case:) Use system.out.println(java.util.Arrays.toString(num)) instead, and see this thread for more details.
String raw = "1233983543587325318";
char[] c = raw.toCharArray();
int[] a = new int[raw.length()];
for (int i = 0; i < raw.length(); i++) {
a[i] = (int)c[i] - 48;
}
You can try like this,
String raw = "1233983543587325318";
char[] list = new char[raw.length()];
list = raw.toCharArray();
int[] num = new int[raw.length()];
for (int i = 0; i < raw.length(); i++) {
num[i] = Integer.parseInt(String.valueOf(list[i]));
}
for (int i: num) {
System.out.print(i);
}
Simple and modern solution
int[] result = new int[raw.length()];
Arrays.setAll(result, i -> Character.getNumericValue(raw.charAt(i)));
Line num[i] = (int[])list[i];
It should be num[i] = (int) list[i];
You are looping through the array so you are casting each individual item in the array.
The reason you got "garbage" is you were printing the int values in the num[] array.
char values are not a direct match for int values.
char values in java use UTF-16 Unicode.
For example the "3" char translates to 51 int
To print out the final int[] back to char use this loop
for(int i:num)
System.out.print((char) i);
I don't see anyone else mentioning the obvious:
We can skip the char array and go directly from String to int array.
Since java 8 we have CharSequence.chars which will return an IntStream so to get an int array, of the char to int values, from a string.
String raw = "1233983543587325318";
int[] num = raw.chars().toArray();
// num ==> int[19] { 49, 50, 51, 51, 57, 56, 51, 53, 52, 51, 53, 56, 55, 51, 50, 53, 51, 49, 56 }
There are also some math reduce functions on Intstream like sum, average, etc. if this is your end goal then we can skip the int array too.
String raw = "1233983543587325318";
int sum = raw.chars().sum();
// sum ==> 995
nJoy!

Replace duplicate numbers with unique numbers from 0-(N-1)

Background:
I have an N-length array of positive random numbers that are certain to contain duplicates.
e.g. 10,4,5,7,10,9,10,9,8,10,5
Edit: N is likely to be 32, or some other power of two about that size.
The Problem:
I am trying to find the fastest way to replace the duplicates with the missing numbers from 0-(N-1). Using the above example, I want a result that looks like this:
10,4,5,7,0,9,1,2,8,3,6
The goal being to have one of each number from 0 to N-1, without just replacing all the numbers with 0-(N-1) (the random order is important).
Edit: It's also important that this replacement is deterministic, i.e. the same input will have the same output (not random).
My solution:
Currently implemented in Java, uses 2 boolean arrays to keep track of used/unused numbers (unique numbers/missing numbers in the range [0,N) ), and has an approximate worst-case runtime of N+N*sqrt(N).
The code follows:
public byte[] uniqueify(byte[] input)
{
boolean[] usedNumbers = new boolean[N];
boolean[] unusedIndices = new boolean[N];
byte[] result = new byte[N];
for(int i = 0; i < N; i++) // first pass through
{
int newIdx = (input[i] + 128) % N; // first make positive
if(!usedNumbers[newIdx]) // if this number has not been used
{
usedNumbers[newIdx] = true; // mark as used
result[i] = newIdx; // save it in the result
}
else // if the number is used
{
unusedIndices[i] = true; // add it to the list of duplicates
}
}
// handle all the duplicates
for(int idx = 0; idx < N; idx++) // iterate through all numbers
{
if(unusedIndices[idx]) // if unused
for(int i = 0; i < N; i++) // go through all numbers again
{
if(!usedNumbers[i]) // if this number is still unused
{
usedNumbers[i] = true; // mark as used
result[i] = idx;
break;
}
}
}
return result;
}
This seems like the fastest I can hope for, but I thought I'd ask the internet, because there are people much more clever than I who may have a better solution.
N.B. Suggestions/solutions do not have to be in Java.
Thank you.
Edit: I forgot to mention that I am converting this to C++. I posted my java implementation because it's more complete.
Use a balanced binary search tree to keep track of used/unused numbers instead of a boolean array. Then you're running time will be n log n.
The most straightforward solution would be this:
Go through the list and build the "unused" BST
Go through the list a second time, keeping track of numbers seen so far in a "used" BST
If a duplicate is found, replace it with a random element of the "unused" BST.
Here is how I would write it.
public static int[] uniqueify(int... input) {
Set<Integer> unused = new HashSet<>();
for (int j = 0; j < input.length; j++) unused.add(j);
for (int i : input) unused.remove(i);
Iterator<Integer> iter = unused.iterator();
Set<Integer> unique = new LinkedHashSet<>();
for (int i : input)
if (!unique.add(i))
unique.add(iter.next());
int[] result = new int[input.length];
int k = 0;
for (int i : unique) result[k++] = i;
return result;
}
public static void main(String... args) {
System.out.println(Arrays.toString(uniqueify(10, 4, 5, 7, 10, 9, 10, 9, 8, 10, 5)));
}
prints
[10, 4, 5, 7, 0, 9, 1, 2, 8, 3, 6]
The fastest way to do this is probably the most straightforward one. I would take a pass through the list of data keeping a count of each distinct value and marking where duplicates appeared. Then it is just a matter of forming a list of unused values and applying them in turn at the places where duplicates were found.
Tempting as it may be to use a C++ List, if speed is of the essence a simple C array is the most efficient.
This program show the principle.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int data[] = { 10, 4, 5, 7, 10, 9, 10, 9, 8, 10, 5 };
int N = sizeof(data) / sizeof(data[0]);
int tally[N];
memset(tally, 0, sizeof(tally));
int dup_indices[N];
int ndups = 0;
// Build a count of each value and a list of indices of duplicate data
for (int i = 0; i < N; i++) {
if (tally[data[i]]++) {
dup_indices[ndups++] = i;
}
}
// Replace each duplicate with the next value having a zero count
int t = 0;
for (int i = 0; i < ndups; i++) {
while (tally[t]) t++;
data[dup_indices[i]] = t++;
}
for (int i = 0; i < N; i++) {
cout << data[i] << " ";
}
return 0;
}
output
10 4 5 7 0 9 1 2 8 3 6
My approach would be
1. copy the array to a Set in Java.
Set will automatically remove duplicates in the fastest complexity possible(because Sun Micro has implemented it, generally their approach is the fastest like.. use of TimSort for sorting etc...)
Calculate size() of the set.
the size will give you no of duplicates present.
now copy array 0-n-1 to the same set... the missing values will get inserted.
I think it is even possible with running time n. The idea is to keep track of items used in the original list and additional items used during processing in a separate array. A possible java implementation looks like this:
int[] list = { 10, 4, 5, 7, 10, 9, 10, 9, 8, 10, 5 };
boolean[] used = new boolean[list.length];
for (int i : list) {
used[i] = true;
}
boolean[] done = new boolean[list.length];
int nextUnused = 0;
Arrays.fill(done, false);
for (int idx = 0; idx < list.length; idx++) {
if (done[list[idx]]) {
list[idx] = nextUnused;
}
done[list[idx]] = true;
while (nextUnused < list.length && (done[nextUnused] || used[nextUnused])) {
nextUnused++;
}
}
System.out.println(Arrays.toString(list));
List<Integer> needsReplaced = newLinkedList<Integer>();
boolean[] seen = new boolean[input.length];
for (int i = 0; i < input.length; ++i) {
if (seen[input[i]]) {
needsReplaced.add(i);
} else {
seen[input[i]] = true;
}
}
int replaceWith = 0;
for (int i : needsReplaced) {
while (seen[replaceWith]) {
++replaceWith;
}
input[i] = replaceWith++;
}
This should behave in about 2n. The list operations are constant time, and even though that second loop looks nested, the outer loop runs significantly less than n iterations, and the inner loop will only run a total of n times.
C# but should be easy to convert to java. O(n).
int[] list = { 0, 0, 6, 0, 5, 0, 4, 0, 1, 2, 3 };
int N = list.length;
boolean[] InList = new boolean[N];
boolean[] Used = new boolean[N];
int[] Unused = new int[N];
for (int i = 0; i < N; i++) InList[list[i]] = true;
for (int i = 0, j = 0; i < N; i++)
if (InList[i] == false)
Unused[j++] = i;
int UnusedIndex = 0;
for (int i = 0; i < N; i++)
{
if (Used[list[i]] == true)
list[i] = Unused[UnusedIndex++];
Used[list[i]] = true;
}
Edit: tried to convert it to java from c#. I don't have java here so it may not compile but should be easy to fix. The arrays may need to be initialized to false if java doesn't do that automatically.

Unusual Merge Sort Failure

I have an unusual problem. I've been implementing Merge Sort and have encountered the following: The method works correctly except on the last pass. Given a random Integer array as input returns an Integer array where the first half and the second half are sorted separately. The merge works correctly except on the last pass. After fiddling with the debugger for a few hours I figured out that "mention point" is always evaluating to false on the last pass, even though it shouldn't based on the values.
All help is appreciated.
public static Integer[] mergeSort(Integer[] input)
{
if (input.length == 1) return input;
int splittle = input.length / 2;
Integer[] first = new Integer[splittle];
Integer[] second = new Integer[input.length - splittle];
for (int i = 0; i < splittle; i++)
first[i] = input[i];
for (int i = splittle; i < input.length; i++)
second[i - splittle] = input[i];
mergeSort(first);
mergeSort(second);
LinkedList<Integer> returner = new LinkedList<Integer>();
PriorityQueue<Integer> sFirst = new PriorityQueue<Integer>();
PriorityQueue<Integer> sSecond = new PriorityQueue<Integer>();
for (int i = 0; i < first.length; i++)
sFirst.offer(first[i]);
for (int i = 0; i < second.length; i++)
sSecond.offer(second[i]);
// while (!sFirst.isEmpty()&&!sSecond.isEmpty())
// returner.add((sFirst.peek()>=sSecond.peek() ?
// sFirst.poll():sSecond.poll()));
// expansion of line above for debugging purposes
while (!sFirst.isEmpty() && !sSecond.isEmpty())
{
int temp = 0;
if (sFirst.peek() >= sSecond.peek())
temp = sFirst.poll(); // Mention point
else
temp = sSecond.poll();
returner.add(temp);
}
while (!sFirst.isEmpty())
returner.add(sFirst.poll());
while (!sSecond.isEmpty())
returner.add(sSecond.poll());
return returner.toArray(new Integer[0]);
}
The problem is inside your while code, and more specific when you use the poll() method.
You had:
if (sFirst.peek() >= sSecond.peek())
temp = sFirst.poll(); // Mention point
else
temp = sSecond.poll();
when you should had:
if (sFirst.peek() >= sSecond.peek())
temp = sSecond.poll(); // Mention point
else
temp = sFirst.poll();
Before, in an input like this:
sFirst = [-9, 1, 2, 9, 89] and sSecond = [4, 15, 18, 23, 31, 123]
you would have if (-9 >= 4) which would be false, so you would do the else part, which would poll() from sSecond although you should poll() from sFirst. -9 should be the first element to be added in the returner list, not 4.
Also (based on ccoakley answer) change, you should use the returned array from mergeSort(), which can be done easily by:
first = mergeSort(first);
second = mergeSort(second);
You can have a look of the working code (after the changes) here.
I hope this helps: why do you have mergeSort return an Integer array, but then not use the return value in your call to mergeSort(first) and mergeSort(second)?
It appears as if part of your code was written to sort the passed in values and part was written to return a sorted array.

Categories