I'm trying to take a String, i.e. $!#, convert each individual symbol to its corresponding ASCII value, it here being 36, 33, 35 and then ending up with an array of integers with each single number stored in a separate index, meaning 3, 6, 3, 3, 3, 5.
In short: From $!# to $,!,# to 36, 33, 35 to 3, 6, 3, 3, 3, 5
Since I am using Processing (wrapper for Java), my SO-research got me so far:
String str = "$!#";
byte[] b = str.getBytes();
for (int i=0; i<b.length; i++){
println(b[i]);
}
I'm ending up with the ASCII values. The byte array b contains [36, 33, 35].
Now if those were to be Strings instead of bytes, I would use String.valueOf(b) to get 363335 and then split the whole thing again into a single digit integer array.
I wonder if this approach is unnecessarily complicated and can be done with less conversion steps. Any suggestions?
Honestly, if I were you, I wouldn't worry too much about "efficiency" until you have an actual problem. Write code that you understand. If you have a problem with efficiency, you'll have to define exactly what you mean: is it taking too many steps? Is it taking too long? What is the size of your input?
Note that the approach you outlined and the approach below are both O(N), which is probably the best you're going to get.
If you have a specific bottleneck inside that O(N) then you should do some profiling to figure out where that is. But you shouldn't bother with micro-optimizations (or shudder premature optimizations) just because you "feel" like something is "inefficient".
To quote from this answer:
...in the absence of measured performance issues you shouldn't optimize because you think you will get a performance gain.
If I were you, I would just use the charAt() function to get each char in the String, and then use the int() function to convert that char into an int. Then you could add those int values to a String (or better yet, a StringBuilder):
String str = "$!#";
StringBuilder digits = new StringBuilder();
for (int i=0; i<str.length(); i++) {
int c = int(str.charAt(i));
digits.append(c);
}
Then you could use the split() function to split them into individual digits:
String[] digitArray = digits.toString().split("");
for (String d : digitArray) {
println(d);
}
Prints:
3
6
3
3
3
5
There are a ton of different ways to do this: you could use the toCharArray() function instead of charAt(), for example. But none of this is going to be any more or less "efficient" until you define exactly what you mean by efficiency.
Java 8 stream solution:
int[] digits = "$!#".chars()
.mapToObj(Integer::toString)
.flatMapToInt(CharSequence::chars)
.map(c -> c - '0')
.toArray();
System.out.println(Arrays.toString(digits)); // prints [3, 6, 3, 3, 3, 5]
One solution could be doing something like that
// Create an array of int of a size 3 * str.length()
for(int i = 0; i < str.length(); i++)
{
int n = (int) str.charAt(i);
int a = n / 100;
int b = (n - (a * 100)) / 10;
int c = n - (a * 100) - (b * 10);
// push a, b and c in your array (chose the order and if you want
// to add the potential 0's or not)
}
But as others said before, I'm not sure if it worth playing like that. It depends on your application I guess.
Related
I am trying to figure out a solution to calculate the highest sum of numbers in an array. However, my limitation is that I cannot use adjacent values in the array.
If I am given the array int [] blocks = new int[] {15, 3, 6, 17, 2, 1, 20}; the highest sum calculated is 52 (15+17+20).
My goal is to go from a recursive solution to a solution that uses dynamic programming, however, I am having trouble with the recursive solution.
The base cases that I have initialized:
if(array.length == 0)
return 0;
if(array.length == 1)
return array[0];
After creating the base cases, I am unsure of how to continue the recursive process.
I initially tried to say that if the array was of certain length, then I can calculate the max(Math.max) of the calculations:
e.g. if array.length = 3
return Math.max(array[0], array[1], array[2], array[0]+ array[2])
The problem I then run into is that I could be given an array of length 100.
How can I use recursion in this problem?
I think recursive solution to your problem is (in pseudocode):
maxsum(A,0) = 0
maxsum(A,1) = A[0]
maxsum(A,k) = max(maxsum(A,k-2)+A[k-1], maxsum(A,k-1)), for k >= 2
Where maxsum(A,k) means the maximal sum for a subarray of array A starting from 0 and having length k. I'm sure you'll easily translate that into Java, it translates almost literally.
I want to iterate just the half of an array in java. Is there any elegant way to shorten this up, eg with a for-each loop?
int[] array = {0,1,2,3,4,5};
for (int i = 0; i<array.length/2; i++)
{
System.out.println(array[i]);
}
If you converted the array into a list using the asList method of the Arrays class in Java, then you can use the forEach method in the List class in Java to print out each element of the list in one single line,
Arrays.asList(array).forEach(System.out::println);
To print only half the array, I'd suggest copying half the array into a new array using the copyOfRange method,
Integer[] newArray = Arrays.copyOfRange(array, 0, array.length/2);
Arrays.asList(newArray).forEach(System.out::println);
EDIT: Like Marko Topolnik pointed out, we're actually starting out with an array of primitive types instead of object types, so in order to use the asList method we're going to have to convert the array into an array of objects (from int to Integer using Integer[] integerArray = ArrayUtils.toObject(array);). However this just seems tedious/inefficient and OP asked for a shorter way so my suggestion would be to use Marko's method,
Arrays.stream(array).limit(array.length/2).forEach(System.out::println);
EDIT 2: Like Amber Beriwal pointed out, it should be noted that although the one-line solution above looks pretty due to its conciseness, it is still very inefficient/slow compared to the OP's original method. Therefore, I would like to reiterate Amber's comments that the OP and others should just stick with the original for-loop.
for (int i = 0; i < array.length/2; i++)
{
System.out.println(array[i]);
}
How about:
IntStream.range(0, array.length / 2).map(i -> array[i]).forEach(System.out::println);
One line, and no array copies.
Broken down:
IntStream.range(0, array.length / 2) //get the range of numbers 0 - (array length)/2
.map(i -> array[i]) //map from index to value
.forEach(System.out::println); //print result
The answer you have posted is good. Although, I couldn't find a better way to make it compact keeping the performance same, but performance can be improved. Remember following practices while coding:
Algorithm's memory requirement should be optimum
Algorithm's time i.e. performance should be optimum
Algorithm's complexity should not be too much. For significant gains in 1 & 2, this can be skipped.
Considering 1 & 2, lines of code comes at least priority.
Solution 1: This solution will be 4-5 times slower than your approach, plus Stream will take extra space.
Arrays.stream(array).limit(array.length/2).forEach(System.out::println);
Solution 2: This solution is faster than the above code and your code (based on my testing), but Stream will take extra space. Also, it is not compact.
Arrays.stream(array).limit(array.length / 2).forEach(new IntConsumer() {
#Override
public void accept(int value) {
System.out.println(value);
}
});
Solution 3: As suggested by you.
int[] array = new int[] { 0, 1, 2, 3, 4, 5 };
int limit = array.length / 2;
for (int i = 0; i < limit; i++) {
System.out.println(array[i]);
}
Recommendation: Don't go over to reduce the LOC at the stake of losing performance and memory. It is better to keep up with the solution that gives you best performance..
I have been given 3 algorithms to reverse engineer and explain how they work, so far I have worked out that I have been given a quick sorting algorithm and a bubble sorting algorithm; however i'm not sure what algorithm this is. I understand how the quick sort and bubble sort work, but I just can't get my head around this algorithm. I'm unsure what the variables are and was hoping someone out there would be able to tell me whats going on here:
public static ArrayList<Integer> SortB(ArrayList<Integer> a)
{
ArrayList<Integer> array = CopyArray(a);
Integer[] zero = new Integer[a.size()];
Integer[] one = new Integer[a.size()];
int i,b;
Integer x,p;
//Change from 8 to 32 for whole integers - will run 4 times slower
for(b=0;b<8;++b)
{
int zc = 0;
int oc = 0;
for(i=0;i<array.size();++i)
{
x = array.get(i);
p = 1 << b;
if ((x & p) == 0)
{
zero[zc++] = array.get(i);
}
else
{
one[oc++] = array.get(i);
}
}
for(i=0;i<oc;++i) array.set(i,one[i]);
for(i=0;i<zc;++i) array.set(i+oc,zero[i]);
}
return(array);
}
This is a Radix Sort, limited to the least significant eight bits. It does not complete the sort unless you change the loop to go 32 times instead of 8.
Each iteration processes a single bit b. It prepares a mask called p by shifting 1 left b times. This produces a power of two - 1, 2, 4, 8, ..., or 1, 10, 100, 1000, 10000, ... in binary.
For each bit, the number of elements in the original array with bit b set to 1 and to 0 are separated into two buckets called one and zero. Once the separation is over, the elements are placed back into the original array, and the algorithm proceeds to the next iteration.
This implementation uses two times more storage than the size of the original array, and goes through the array a total of 16 times (64 times in the full version - once for reading and once for writing of data for each bit). The asymptotic complexity of the algorithm is linear.
Looks like a bit-by-bit radix sort to me, but it seems to be sorting backwards.
Studying for exams I have been given a lot of code to manually compute. This question its throwing me for a loop.
public static int[] mystery(int x) {
int[] result = new int[x / 2];
for (int i = 0; i < x/2; i++) {
result[i] = (i * i) % x;
}
return result;
}
for:
mystery(5)
mystery(10)
What I computed was [0, 1] for mystery(5) and [0, 1, 4, 4, 1] for mystery(10); however, I believe that those answers are not correct.
When going about questions like these, what strategies may help lead me to the answer faster?
Also if you conclude to an answer what were the steps you took to arrive at the answer?
Your answer to mystery(5) is correct.
The array for mystery(10) should contain [0,1,4,9,6], since you're calculating square numbers mod 10 in this case.
In my opinion there is really no strategy to get a result faster. It's all about experience in reading the code.
The steps I took for this particular answer were basically
look at the argument (x=10)
look where the argument appears and insert it
go through the code step by step
look at first line -> int division -> array has size 5
look at for loop, insert argument and work with concrete numbers -> for(int i = 0; i < 5; i++) => so i goes from 0 to 4
look at expression and decide, which values are changing and which ones are fixed -> result[i] = (i*i)%10;
Think, what loop does => ith square number mod 10 goes into array at index i
So result should be [0,1,4,9,6]
The key thing you should observe when reading this method is that the iterations of the loop are data-flow independent; the effect of iteration i can be analyzed in isolation, without needing to know what happened at any other iterations.
Thus there's really only one fact you need to be thinking about: resulti = i2 mod x. Then you can forget about the code and just do the math.
Where x = 10:
result0 = 02 mod 10 = 0
result1 = 12 mod 10 = 1
result2 = 22 mod 10 = 4
result3 = 32 mod 10 = 9
result4 = 42 mod 10 = 6
Given an array of positive integers. All numbers occur even number of times except one number which occurs odd number of times. Find the number in O(n) time & constant space.
int getOddOccurrence ( int ar[]){
int i;
int res = 0;
for (i = 0; i < ar.size; i++)
res = res ^ ar[i];
return res;
}
/* Diver function to test above function */
PSVM() {
int ar[] = {2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2};
SOP(getOddOccurrence(ar));
}
Approach 1: By X-OR ing all the elements in an array
I am trying to x-or all the elements. Is that the
correct approach? Above is the code using X-OR
Approach 2: By using HashMap
If I use hashmap , the space complexity would be O(n). Which is not good.
Which approach should I use?
This problem assumes there is only one number which occurs odd number of
times in the array. If you have more such numbers - say K of them: a1, a2, ... aK,
then at the end of the loop, in res you will get this value.
res == a1 ^ a2 ^ ... ^ aK
From that value you cannot infer/extract all K unknown numbers a1, a2, ... aK.
Buf ... you see, if K=1 (i.e. if you have exactly one number occurring
odd number of times), at the end you will get in res just that number.
Use the first approach as long as you understand why it works.
Also, in the second approach the space is not O(n) but O(s),
where s is the count of distinct values in your array. And as you
have only 1 number occurring odd number of times we can say for sure
that 2*s + 1 <= n i.e. s <= (n-1)/2. So the space complexity
is O((n-1)/2) in the second approach. You achieve it when your array
looks like this: s numbers occurring twice, and 1 number occurring once.