sorting strings in an array alphabetically - arrays

I came up with this code to try and sort out an array of strings (I don't want to use ints or imports as I'm trying to understand iteration loops), but it only rearranges the first two strings. Can anyone point out my mistakes?
public class Alpha8 {
public static void main(String[] args) {
String[] Names = {"O","B","K","S","D","M","N","A"};
String temp = null;
for(int i=0;i<Names.length;i++){
for(int j = i+1;j<Names.length;j++) {
if(Names[j].compareTo(Names[i])<0)
temp = Names[i];
Names[i] = Names[j];
Names[j] = temp;
for( i = 0;i<Names.length;i++){
System.out.println(Names[i]);
}
}
}
}
}

You have made two mistakes:
You are printing the array inside your 'swap' code. You should only print the array once the sorting is complete.
You only iterate through the array once. For a bubble sort (which is what you are implementing) you need to keep iterating through until no swaps occur.
The method should look something like:
boolean hasSwapped;
do {
hasSwapped = false;
for (int i = 1; i < names.size(); i++) {
if (names[i-1].compareTo(names[i]) > 0) {
swap(names[i-1], names[i]);
hasSwapped = true;
}
}
} while (hasSwapped);

Related

Deleting Elements in Array equal to a value

I'm trying to make a code that removes all the elements from the array that are equal to a given value. For example an array = [hi, hello, hi, bye] value = hi, it would given an output hello bye
Here's my code:
int count = 0;
for(int i=0; i<stringArr.length;
if(stringArr[i].equals(value)){
count--;
for(int j= i; j<stringArr.length-1; j++){
stringArr[j] = stringArr[j+1];
}
i--;
}
}
Problem is instead of the expected output as: hello bye
It gives an output of:
hello hi bye bye
Try Java stream api:
String value = "hi";
String[] stringArr = new String[] {"hi", "hello", "hi", "bye"};
String[] results = Arrays.stream(stringArr)
.filter(it -> !it.equalsIgnoreCase(value))
.toArray(String[]::new);
The problem is that you are shifting the values left but not decrementing the length of the array in the outer for.
Assign stringArr.length to count and use it in the for.
Trading memory for speed, you could create a new array of the same length and only add in the first occurrence of what you want.
String[] removeEqual(String[]array,String val){
boolean found =false;
String[]out=new String[array.length];
int count=0;
for (int i=0;i<array.length;i++){
if(array[i].equals(val)){
if(!found){
out[count++]=val;
found=true;
}
else out[count++]=val;
}
}
return Arrays.copyOf(out, count);
}
You may like to consider separate functions for separate conditions such as removeLessThan and removeGreaterThan to keep it functionally coherent.
I don't recommend to do any manipulation to the original array, create a new one. Recycling is good for the planet, but may be very harmful in code. So if you want to stick to the Arrays only, then create a new array with and add all elements you want into the new array, but I think you can do better. Your approach is very "C" like, this is Java, you have a lot of better tools, than arrays.
One of them are streams and lambdas like this
#Test
public void example_lambdas() {
String[] array = {"hi", "hello", "hi", "bye"};
String[] result = Arrays.stream(array).filter(element -> !"hi".equals(element)).toArray(String[]::new);
System.out.println(Arrays.toString(result));
}
Another option is to use list
#Test
public void example_list() {
String[] array = {"hi", "hello", "hi", "bye"};
List<String> list = new ArrayList<>(Arrays.asList(array));
Set<String> toBeRemoved = Collections.singleton("hi");
list.removeAll(toBeRemoved);
String[] result = list.toArray(new String[0]);
System.out.println(Arrays.toString(result));
}
An array has a fixed size that cannot be changed. Hence your result cannot be a two element array when you start with a four element array. If you want the result to be a two element array, then you will need to create a second array. If, however, you want the result to stay in the original array, then I suggest setting the excess array elements to null. The following code demonstrates.
String[] stringArr = {"hi", "hello", "hi", "bye"};
String condition = "==";
String value = "hi";
int count = stringArr.length;
for (int i = 0; i < count; i++) {
if (condition.equals("==")) {
if (stringArr[i].equals(value)) {
count--;
for (int j = i; j < stringArr.length - 1; j++) {
stringArr[j] = stringArr[j + 1];
}
stringArr[stringArr.length - 1] = null;
}
}
}
System.out.println(java.util.Arrays.toString(stringArr));
The above code prints the following:
[hello, bye, null, null]
EDIT
As requested, below code creates a new array that only contains the requested elements, i.e. the ones that were not removed from the original array.
String[] stringArr = {"hi", "hello", "hi", "bye"};
String condition = "==";
String value = "hi";
String[] temp = new String[stringArr.length];
int count = 0;
for (int i = 0; i < stringArr.length; i++) {
if (condition.equals("==")) {
if (!stringArr[i].equals(value)) {
temp[count++] = stringArr[i];
}
}
}
String[] result = new String[count];
for (int i = 0; i < count; i++) {
result[i] = temp[i];
}
System.out.println(Arrays.toString(result));
The above code prints the following:
[hello, bye]
In other words, result is a two element array.
Note that I assume that you only want to do array manipulation and you don't want to use classes in the JDK that most of the other answers have used.

Given an array in which arr[i] = i-1 with the following method, what will be the output?

I'm given the following method written in pseudo-code
for i=1 to floor(n/2)
if arr[i] != 0 then
for(j=2 to floor(n/i)
arr[i*j] = 0
I need to find the output and to prove that it's indeed the output.
So far I tried to write the code in Java and to try different inputs and array sizes but to no avail.
Putting it here if it's of any help:
public class Checking
{
private static int method(int[] A,int n)
{
for (int i=1;i<=java.lang.Math.floor(n/2);i++)
{
if(A[i] != 0)
{
for(int j=2;j<=java.lang.Math.floor(n/i);j++)
{
A[i*j]=0;
System.out.println("The index ofA["+i*j+"] became "+A[i*j]);
}
}
//System.out.print(", "+A[i]);
}
for (int i=1;i<=java.lang.Math.floor(n/2);i++)
{
System.out.print(", "+A[i]);
}
return 0;
}
public static void main(String[] args)
{
int[] A = {-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
System.out.println(method(A,20));
}
}
Thank you.
You can change the following:
In your main method remove
System.out.println(method(A,20));
as it will always print 0 as you return 0; from the method().
As you print everything in your method() change the following (as it does not print the full array but from index 1 (missing index 0) to floor n/2)
for (int i=1;i<=java.lang.Math.floor(n/2);i++)
{
System.out.print(", "+A[i]);
}
to
for (int i=0;i<A.length; i++)
{
System.out.print(", "+A[i]);
}
So you can print the whole array.
For simplicity you can use Array's print method to print the array without a for loop
System.out.println(Arrays.toString(A));

If the input is a1bc2def3 output should be abcbcdefdef

If the given input is a1bc2def3 then output should be abcbcdefdefdef
Whenever the number comes then we should repeat previous substring that many number of times.
Please provide the algorithm or code to accomplish this.
Here's another approach that doesn't rely on regex.
public String splitRepeat(String str)
{
StringBuilder out = new StringBuilder();
boolean number = false;
for(int i=0,j=0,k=0; i<=str.length(); i++)
{
if(i==str.length() || Character.isDigit(str.charAt(i)) != number)
{
if(number)
{
for(int r = Integer.parseInt(str.substring(j, i)); r>0; r--)
{
out.append(str.substring(k, j));
}
}
else
{
k=j;
}
j=i;
number = !number;
}
}
return out.toString();
}
My suggestion would be:
Try using regex so you can get an array of numbers and characters,
then convert the number Parsable elements of the array into an integer,
after that loop with the index of the arrays to append n-times the characters of the array
then print the final result
Example:
public static void main(String[] args) {
String stringToProcess = "a1bc2def3";
String[] regexSplitted = stringToProcess.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
StringBuilder sb = new StringBuilder();
String appender = "";
for (int i = 0; i < regexSplitted.length; i++) {
try {
int kilo = Integer.parseInt(regexSplitted[i]);
for (int j = 0; j < kilo; j++) {
sb.append(appender).append(regexSplitted[i - 1]);
appender = "-";
}
} catch (NumberFormatException e) {
}
}
System.out.println(sb.toString());
}
this will print
a-bc-bc-def-def-def
that is pretty much what you are looking for.

compare two int array in j2me?

In my app I have 2 images with same dimensions,that I would to give their RGB data and compare them.In j2me we can not use java.util.Arrays and so Arrays.equals(array1, array2) method. One way to compare them is using for loop and compare each element of two int array,but i'm looking for better way.When I search in web I found ArrayUtils class,here,that has some equals() methods,but it's method compare two arrays of objects and before compare int arrays convert them to Enumeration by arrayToEnumeration(Object array) that creates an enumeration from given object.
Finally this is my question:
Is there a better way to compare two int arrays in j2me?
Try something like this.. From the Util class
public static boolean equals(byte[] a, byte[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
private int compareArray(String[] _array1, String[] _array2){
Vector m_length1 = new Vector();
Vector m_length2 = new Vector();
if(_array1 && _array2!=null)
{
for(int i=0; i<_array1.length; i++){
if(m_length1[i]!=null){
m_length1.add(_array1[i]);
}
}
for(int j=0; j<_array2.length; j++){
if(m_length2[j]!=null){
m_length2.add(_array2[j]);
}
}
}
if(m_length1.size()==m_length2.size()){
return 0; /*matching*/
}else{
return -1; /*no matching*/
}
}
You can modify it as int array or you can compare byte of each value.
For instance;
byte sample[] = {0,0,0,0};
sample= yourValue.getBytes();
Convert byte array to String:
public boolean equals(byte[] b1, byte[] b2){
String strB1 = new String(b1);
String strB2 = new String(b2);
if(strB1.equals(strB2)){
return true;
}
else{
return false;
}
}

Generating All Permutations of Character Combinations when # of arrays and length of each array are unknown

I'm not sure how to ask my question in a succinct way, so I'll start with examples and expand from there. I am working with VBA, but I think this problem is non language specific and would only require a bright mind that can provide a pseudo code framework. Thanks in advance for the help!
Example:
I have 3 Character Arrays Like So:
Arr_1 = [X,Y,Z]
Arr_2 = [A,B]
Arr_3 = [1,2,3,4]
I would like to generate ALL possible permutations of the character arrays like so:
XA1
XA2
XA3
XA4
XB1
XB2
XB3
XB4
YA1
YA2
.
.
.
ZB3
ZB4
This can be easily solved using 3 while loops or for loops. My question is how do I solve for this if the # of arrays is unknown and the length of each array is unknown?
So as an example with 4 character arrays:
Arr_1 = [X,Y,Z]
Arr_2 = [A,B]
Arr_3 = [1,2,3,4]
Arr_4 = [a,b]
I would need to generate:
XA1a
XA1b
XA2a
XA2b
XA3a
XA3b
XA4a
XA4b
.
.
.
ZB4a
ZB4b
So the Generalized Example would be:
Arr_1 = [...]
Arr_2 = [...]
Arr_3 = [...]
.
.
.
Arr_x = [...]
Is there a way to structure a function that will generate an unknown number of loops and loop through the length of each array to generate the permutations? Or maybe there's a better way to think about the problem?
Thanks Everyone!
Recursive solution
This is actually the easiest, most straightforward solution. The following is in Java, but it should be instructive:
public class Main {
public static void main(String[] args) {
Object[][] arrs = {
{ "X", "Y", "Z" },
{ "A", "B" },
{ "1", "2" },
};
recurse("", arrs, 0);
}
static void recurse (String s, Object[][] arrs, int k) {
if (k == arrs.length) {
System.out.println(s);
} else {
for (Object o : arrs[k]) {
recurse(s + o, arrs, k + 1);
}
}
}
}
(see full output)
Note: Java arrays are 0-based, so k goes from 0..arrs.length-1 during the recursion, until k == arrs.length when it's the end of recursion.
Non-recursive solution
It's also possible to write a non-recursive solution, but frankly this is less intuitive. This is actually very similar to base conversion, e.g. from decimal to hexadecimal; it's a generalized form where each position have their own set of values.
public class Main {
public static void main(String[] args) {
Object[][] arrs = {
{ "X", "Y", "Z" },
{ "A", "B" },
{ "1", "2" },
};
int N = 1;
for (Object[] arr : arrs) {
N = N * arr.length;
}
for (int v = 0; v < N; v++) {
System.out.println(decode(arrs, v));
}
}
static String decode(Object[][] arrs, int v) {
String s = "";
for (Object[] arr : arrs) {
int M = arr.length;
s = s + arr[v % M];
v = v / M;
}
return s;
}
}
(see full output)
This produces the tuplets in a different order. If you want to generate them in the same order as the recursive solution, then you iterate through arrs "backward" during decode as follows:
static String decode(Object[][] arrs, int v) {
String s = "";
for (int i = arrs.length - 1; i >= 0; i--) {
int Ni = arrs[i].length;
s = arrs[i][v % Ni] + s;
v = v / Ni;
}
return s;
}
(see full output)
Thanks to #polygenelubricants for the excellent solution.
Here is the Javascript equivalent:
var a=['0'];
var b=['Auto', 'Home'];
var c=['Good'];
var d=['Tommy', 'Hilfiger', '*'];
var attrs = [a, b, c, d];
function recurse (s, attrs, k) {
if(k==attrs.length) {
console.log(s);
} else {
for(var i=0; i<attrs[k].length;i++) {
recurse(s+attrs[k][i], attrs, k+1);
}
}
}
recurse('', attrs, 0);
EDIT: Here's a ruby solution. Its pretty much the same as my other solution below, but assumes your input character arrays are words: So you can type:
% perm.rb ruby is cool
~/bin/perm.rb
#!/usr/bin/env ruby
def perm(args)
peg = Hash[args.collect {|v| [v,0]}]
nperms= 1
args.each { |a| nperms *= a.length }
perms = Array.new(nperms, "")
nperms.times do |p|
args.each { |a| perms[p] += a[peg[a]] }
args.each do |a|
peg[a] += 1
break if peg[a] < a.length
peg[a] = 0
end
end
perms
end
puts perm ARGV
OLD - I have a script to do this in MEL, (Maya's Embedded Language) - I'll try to translate to something C like, but don't expect it to run without a bit of fixing;) It works in Maya though.
First - throw all the arrays together in one long array with delimiters. (I'll leave that to you - because in my system it rips the values out of a UI). So, this means the delimiters will be taking up extra slots: To use your sample data above:
string delimitedArray[] = {"X","Y","Z","|","A","B","|","1","2","3","4","|"};
Of course you can concatenate as many arrays as you like.
string[] getPerms( string delimitedArray[]) {
string result[];
string delimiter("|");
string compactArray[]; // will be the same as delimitedArray, but without the "|" delimiters
int arraySizes[]; // will hold number of vals for each array
int offsets[]; // offsets will holds the indices where each new array starts.
int counters[]; // the values that will increment in the following loops, like pegs in each array
int nPemutations = 1;
int arrSize, offset, nArrays;
// do a prepass to find some information about the structure, and to build the compact array
for (s in delimitedArray) {
if (s == delimiter) {
nPemutations *= arrSize; // arrSize will have been counting elements
arraySizes[nArrays] = arrSize;
counters[nArrays] = 0; // reset the counter
nArrays ++; // nArrays goes up every time we find a new array
offsets.append(offset - arrSize) ; //its here, at the end of an array that we store the offset of this array
arrSize=0;
} else { // its one of the elements, not a delimiter
compactArray.append(s);
arrSize++;
offset++;
}
}
// put a bail out here if you like
if( nPemutations > 256) error("too many permutations " + nPemutations+". max is 256");
// now figure out the permutations
for (p=0;p<nPemutations;p++) {
string perm ="";
// In each array at the position of that array's counter
for (i=0;i<nArrays ;i++) {
int delimitedArrayIndex = counters[i] + offsets[i] ;
// build the string
perm += (compactArray[delimitedArrayIndex]);
}
result.append(perm);
// the interesting bit
// increment the array counters, but in fact the program
// will only get to increment a counter if the previous counter
// reached the end of its array, otherwise we break
for (i = 0; i < nArrays; ++i) {
counters[i] += 1;
if (counters[i] < arraySizes[i])
break;
counters[i] = 0;
}
}
return result;
}
If I understand the question correctly, I think you could put all your arrays into another array, thereby creating a jagged array.
Then, loop through all the arrays in your jagged array creating all the permutations you need.
Does that make sense?
it sounds like you've almost got it figured out already.
What if you put in there one more array, call it, say ArrayHolder , that holds all of your unknown number of arrays of unknown length. Then, you just need another loop, no?

Resources