Bubble Sort Array with unknown length (Java)? - java

This is Java through my university so there are some components in here that you may not know. Do not pay attention for them because they are not the problem.
My compiler made me initialize my array to null. I then try to run the rest of my program and it said that it is supposed to work with an array that has actual values in it. My question is how should I go about doing this?
private static String[] alphabetSort(Map<String, Integer> mapWord) {
String[] ordered = null;
Map<String, Integer> copy = mapWord;
for (int i = 0; i < copy.size(); i++) {
Map.Pair<String, Integer> pair = copy.removeAny();
String key = pair.key();
ordered[i] = key;
}
boolean flag = true;
String temp;
while (flag) {
flag = false;
for (int j = 0; j < ordered.length; j++) {
String test1 = ordered[j];
String test2 = ordered[j + 1];
if (test1.compareTo(test2) < 0) {
temp = ordered[j];
ordered[j] = ordered[j + 1];
ordered[j + 1] = temp;
flag = true;
}
}
}
return ordered;
}

Arrays have fixed-size. You have to pick a size when you're creating it.
Try:
String[] ordered = new String[mapWord.size()];

Related

Reformat a String array

I would like to re-format a String array based on condition. Say, the array
A = ["samsung", "chargers", "fast", "charging", "rapid", "high"]
int index = 1
Which means I will adjoin the items till index 1 with space and format the array. So, finally, it will be,
A = ["samsung chargers", "fast", "charging", "rapid", "high"]
For the index = 2, the output should be,
A = ["samsung chargers fast", "charging", "rapid", "high"]
I write the code that works, I try to find more concise (but not low performance) way.
StringBuilder builder = null;
..........
int fCount = ...
// format the array to match the string
// values = ["samsung", "chargers", "fast", "charging", "rapid", "high"]
builder = new StringBuilder();
String formated = "";
for (int i = 0; i <= fCount; i++) {
builder.append(values[i]).append(" ");
}
formated = builder.toString().trim();
String[] fVaues = new String[values.length - fCount];
fVaues[0] = formated;
for (int i = 1; i < fVaues.length; i++) {
fVaues[i] = values[i+1];
}
What is the simple way to accomplish it?
This method does the same thing:
static String[] joinUntil(String[] original, int until) {
return Stream.concat(
Stream.of(String.join(" ", Arrays.copyOf(original, until))),
Arrays.stream(Arrays.copyOfRange(original, until, original.length))
).toArray(String[]::new);
}
private static List<String> reFormat(List<String> lst, int index){
String joined = String.join(" ", lst.subList(0, index + 1));
List<String> res = new ArrayList<String>();
res.add(joined);
res.addAll(lst.subList(index + 1, lst.size()));
return res;
}
You could just loop over it, adding the Strings to a second array:
String[] b = new String[a.length - index];
String tmp = a[0];
for(int i = 1; i < a.length; i++) {
if(i <= index) {
tmp += " " + a[i];
if(i == index) {
b[i - index] = tmp;
}
}
else {
b[i - index] = a[i];
}
}

How do I sort a method list in Java?

Down below you'll see an outtake of my code. I need to sort the getTopBids so that the highest bid comes first and after that the second highest one etc.... How do I do this? Very new to Java - this is my first assignment in school!
public String getTopBids(){
StringBuilder topBids = new StringBuilder();
ArrayList<String> topBidsName = new ArrayList<>();
ArrayList<Integer> topBidsAmount = new ArrayList<>();
for(int i = 0; i < 3; i++) {
String name = "";
int amount = 0;
for (Bid bid : this.getBidding()) {
if(amount < bid.getAmount() && !topBidsAmount.contains(bid.getAmount())) {
name = bid.getUser().getName();
amount = bid.getAmount();
}
}
if(amount != 0){
topBidsName.add(name);
topBidsAmount.add(amount);
}
}
for (int i = 0; i < topBidsName.size(); i++){
topBids.append(String.format("%s %d kr", topBidsName.get(i),
topBidsAmount.get(i)));
if(i != topBidsName.size()) topBids.append(", ");
}
return topBids.toString(); }
}
Use
Collections.sort(topBidsAmount);
See also How to use Collections.sort() in Java?

How to move a null to the end of array in java using FOR loop?

Assume there is only one null in an array. I am trying to move it right to the end using a for loop. this is what i tried.
String example[] = new String[5];
example[0] = "a";
example[1] = null;
example[2] = "c";
example[3] = "d";
example[4] = "e";
I want the output to be : a,c,d,e,null. I want to able to move the null to the end regardless of its index using a FOR loop.
This is what i tried
String asd[] = new String[creatureList.length];
for (int i = 0 ; i < creatureList.length; i++) {
if (creatureList[i] != null){
asd[i] = creatureList[i];
}
creatureList = asd;
Just search for the null element and if found, shift all elements 1 position to the left. This code works even if there are more than 1 null elements in the array.
public class Test10 {
public static void main(String[] args) {
String example[] = new String[5];
example[0] = "a";
example[1] = null;
example[2] = "c";
example[3] = "d";
example[4] = "e";
for (int j=0; j<example.length; j++){
if (example[j]==null){
for (int k=j+1; k<example.length; k++){
example[k-1] = example[k];
}
example[example.length-1] = null;
break;
}
}
for (int j=0; j<example.length; j++){
System.out.println(example[j]);
}
}
}
You can just use the principle of bubble sort in here.
Try this
String example[] = new String[5];
example[0] = "a";
example[1] = null;
example[2] = "c";
example[3] = "d";
example[4] = "e";
for(int i=0; i < example.length - 1; ++i) {
if(example[i] == null) {
example[i] = example[i+1];
example[i+1] = null;
}
}
for(String s : example)
System.out.print(s + " ");
If you only need to print the values that way, try this
for(String s : example)
if(s != null)
System.out.print(s + " ");
System.out.print(null + " ");
A possible solution without creating a new Array would be to move the elements.
Example, assuming that example is an Array:
boolean found = false;
for(int i = 0; i < example.length; i++) {
if(found)
example[i-1] = example[i];
if(example[i] == null)
found = true;
if(i == example.length - 1 && found)
example[i] = null;
}
I want to add that this would be a lot easier if you would use Collections (for example an ArrayList), I highly recommend using them instead of Arrays if performance is not a huge factor.
I'd have a different implementation for ArrayLists (as .remove() is handy), but here we are with a bounded array:
for(int n = 0; n < array.length; n++) {
if(null == array[n]) {
// to avoid issues with references, unsure if necessary
String s = array[n + 1];
array[n] = array[s];
array[n + 1] = null;
}
}
Here's a solution that is based on your assumption that there's only one null:
for (int i=1; i<example.length; i++) {
if (example[i-1] == null) {
example[i-1] = example[i];
example[i] = null;
}
}
I think the answers before me were not correct, so here is a code that works and puts all the nulls at the end of a array.
public static void moveNullToTheEnd( Object[] arr )
{
Object[] temp = new Object[arr.length];
int counter = 0;
int nullcounter = arr.length-1;
for(int i= 0; i < arr.length; i++) {
if(arr[i] == null){
temp[nullcounter] = null;
nullcounter--;
}
else {
temp[counter] = arr[i];
counter++;
}
}
arr = temp;
System.out.println(Arrays.toString(arr));
}
public static void main (String[] args)
{
Object [] test = new Object[] {1, 2, null, null, 4};
moveNullToTheEnd(test);
}

Smart way to generate permutation and combination of String

String database[] = {'a', 'b', 'c'};
I would like to generate the following strings sequence, based on given database.
a
b
c
aa
ab
ac
ba
bb
bc
ca
cb
cc
aaa
...
I can only think of a pretty "dummy" solution.
public class JavaApplication21 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
char[] database = {'a', 'b', 'c'};
String query = "a";
StringBuilder query_sb = new StringBuilder(query);
for (int a = 0; a < database.length; a++) {
query_sb.setCharAt(0, database[a]);
query = query_sb.toString();
System.out.println(query);
}
query = "aa";
query_sb = new StringBuilder(query);
for (int a = 0; a < database.length; a++) {
query_sb.setCharAt(0, database[a]);
for (int b = 0; b < database.length; b++) {
query_sb.setCharAt(1, database[b]);
query = query_sb.toString();
System.out.println(query);
}
}
query = "aaa";
query_sb = new StringBuilder(query);
for (int a = 0; a < database.length; a++) {
query_sb.setCharAt(0, database[a]);
for (int b = 0; b < database.length; b++) {
query_sb.setCharAt(1, database[b]);
for (int c = 0; c < database.length; c++) {
query_sb.setCharAt(2, database[c]);
query = query_sb.toString();
System.out.println(query);
}
}
}
}
}
The solution is pretty dumb. It is not scale-able in the sense that
What if I increase the size of database?
What if my final targeted print String length need to be N?
Is there any smart code, which can generate scale-able permutation and combination string in a really smart way?
You should check this answer: Getting every possible permutation of a string or combination including repeated characters in Java
To get this code:
public static String[] getAllLists(String[] elements, int lengthOfList)
{
//lists of length 1 are just the original elements
if(lengthOfList == 1) return elements;
else {
//initialize our returned list with the number of elements calculated above
String[] allLists = new String[(int)Math.pow(elements.length, lengthOfList)];
//the recursion--get all lists of length 3, length 2, all the way up to 1
String[] allSublists = getAllLists(elements, lengthOfList - 1);
//append the sublists to each element
int arrayIndex = 0;
for(int i = 0; i < elements.length; i++){
for(int j = 0; j < allSublists.length; j++){
//add the newly appended combination to the list
allLists[arrayIndex] = elements[i] + allSublists[j];
arrayIndex++;
}
}
return allLists;
}
}
public static void main(String[] args){
String[] database = {"a","b","c"};
for(int i=1; i<=database.length; i++){
String[] result = getAllLists(database, i);
for(int j=0; j<result.length; j++){
System.out.println(result[j]);
}
}
}
Although further improvement in memory could be made, since this solution generates all solution to memory first (the array), before we can print it. But the idea is the same, which is to use recursive algorithm.
This smells like counting in binary:
001
010
011
100
101
...
My first instinct would be to use a binary counter as a "bitmap" of characters to generate those the possible values. However, there are several wonderful answer to related questions here that suggest using recursion. See
How do I make this combinations/permutations method recursive?
Find out all combinations and permutations - Java
java string permutations and combinations lookup
http://www.programmerinterview.com/index.php/recursion/permutations-of-a-string/
Java implementation of your permutation generator:-
public class Permutations {
public static void permGen(char[] s,int i,int k,char[] buff) {
if(i<k) {
for(int j=0;j<s.length;j++) {
buff[i] = s[j];
permGen(s,i+1,k,buff);
}
}
else {
System.out.println(String.valueOf(buff));
}
}
public static void main(String[] args) {
char[] database = {'a', 'b', 'c'};
char[] buff = new char[database.length];
int k = database.length;
for(int i=1;i<=k;i++) {
permGen(database,0,i,buff);
}
}
}
Ok, so the best solution to permutations is recursion. Say you had n different letters in the string. That would produce n sub problems, one for each set of permutations starting with each unique letter. Create a method permutationsWithPrefix(String thePrefix, String theString) which will solve these individual problems. Create another method listPermutations(String theString) a implementation would be something like
void permutationsWithPrefix(String thePrefix, String theString) {
if ( !theString.length ) println(thePrefix + theString);
for(int i = 0; i < theString.length; i ++ ) {
char c = theString.charAt(i);
String workingOn = theString.subString(0, i) + theString.subString(i+1);
permutationsWithPrefix(prefix + c, workingOn);
}
}
void listPermutations(String theString) {
permutationsWithPrefix("", theString);
}
i came across this question as one of the interview question. Following is the solution that i have implemented for this problem using recursion.
public class PasswordCracker {
private List<String> doComputations(String inputString) {
List<String> totalList = new ArrayList<String>();
for (int i = 1; i <= inputString.length(); i++) {
totalList.addAll(getCombinationsPerLength(inputString, i));
}
return totalList;
}
private ArrayList<String> getCombinationsPerLength(
String inputString, int i) {
ArrayList<String> combinations = new ArrayList<String>();
if (i == 1) {
char [] charArray = inputString.toCharArray();
for (int j = 0; j < charArray.length; j++) {
combinations.add(((Character)charArray[j]).toString());
}
return combinations;
}
for (int j = 0; j < inputString.length(); j++) {
ArrayList<String> combs = getCombinationsPerLength(inputString, i-1);
for (String string : combs) {
combinations.add(inputString.charAt(j) + string);
}
}
return combinations;
}
public static void main(String args[]) {
String testString = "abc";
PasswordCracker crackerTest = new PasswordCracker();
System.out.println(crackerTest.doComputations(testString));
}
}
For anyone looking for non-recursive options, here is a sample for numeric permutations (can easily be adapted to char. numberOfAgents is the number of columns and the set of numbers is 0 to numberOfActions:
int numberOfAgents=5;
int numberOfActions = 8;
byte[][]combinations = new byte[(int)Math.pow(numberOfActions,numberOfAgents)][numberOfAgents];
// do each column separately
for (byte j = 0; j < numberOfAgents; j++) {
// for this column, repeat each option in the set 'reps' times
int reps = (int) Math.pow(numberOfActions, j);
// for each column, repeat the whole set of options until we reach the end
int counter=0;
while(counter<combinations.length) {
// for each option
for (byte i = 0; i < numberOfActions; i++) {
// save each option 'reps' times
for (int k = 0; k < reps; k++)
combinations[counter + i * reps + k][j] = i;
}
// increase counter by 'reps' times amount of actions
counter+=reps*numberOfActions;
}
}
// print
for(byte[] setOfActions : combinations) {
for (byte b : setOfActions)
System.out.print(b);
System.out.println();
}
// IF YOU NEED REPEATITION USE ARRAYLIST INSTEAD OF SET!!
import java.util.*;
public class Permutation {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
System.out.println("ENTER A STRING");
Set<String> se=find(in.nextLine());
System.out.println((se));
}
public static Set<String> find(String s)
{
Set<String> ss=new HashSet<String>();
if(s==null)
{
return null;
}
if(s.length()==0)
{
ss.add("");
}
else
{
char c=s.charAt(0);
String st=s.substring(1);
Set<String> qq=find(st);
for(String str:qq)
{
for(int i=0;i<=str.length();i++)
{
ss.add(comb(str,c,i));
}
}
}
return ss;
}
public static String comb(String s,char c,int i)
{
String start=s.substring(0,i);
String end=s.substring(i);
return start+c+end;
}
}
// IF YOU NEED REPEATITION USE ARRAYLIST INSTEAD OF SET!!

How to find the longest repeated substring of given string

I am new java and I was given assignment to find the longest substring of a string.
I research online and seems that good way of approaching this problem will be implementing suffix tree.
Please let me know how I can do this or if you have any other solutions. keep in mind this is suppose to be done with low level of java knowledge.
Thanks in adavance.
P.S. the tester string is reassuring.
/**
This method will find the longest substring of a given string.
String given here is reassuring.
*/
public String longestRepeatedSubstring()
{
String longestRepeatedSubstring = "";
for (int i = 0; i<text.length(); i++ )
{
String one = text.substring(0,i);
for(int o = 0; o<text.length();o++)
{
Sting two = text.substring(0,o);
if(one.equals(two))
{
longestRepeatedSubstring = one;
}
}
}
return longestRepeatedSubstring;
}
If you debug your code you will see that you the code isn't doing what you think. AFAIK you need at least three loops and you can't assume you would only start from the first character. Here is one possible solution.
public static void main(String[] args) throws IOException {
String longest = longestDuplicate("ababcaabcabcaab");
System.out.println(longest);
}
public static String longestDuplicate(String text) {
String longest = "";
for (int i = 0; i < text.length() - 2 * longest.length() * 2; i++) {
OUTER:
for (int j = longest.length() + 1; j * 2 < text.length() - i; j++) {
String find = text.substring(i, i + j);
for (int k = i + j; k <= text.length() - j; k++) {
if (text.substring(k, k + j).equals(find)) {
longest = find;
continue OUTER;
}
}
break;
}
}
return longest;
}
prints
abcaab
for "reassuring" it prints r not s which was my first guess. ;)
public static void main(String[] args) {
String str = "testingString";
char[] strArr = str.toCharArray();
StringBuilder bm = new StringBuilder();
boolean isPresent = false;
int len = strArr.length;
int initial =0;
int dinitial=0;
HashMap<String, String> hm = new HashMap<String,String>();
HashMap<String, String> hl = new HashMap<String,String>();
while(initial<=len-1 && !(dinitial>=len-1)){
if(!hm.isEmpty()){
isPresent = hm.containsValue(strArr[initial]+"");
if(!isPresent){
bm.append(strArr[initial]);
hm.put(strArr[initial]+"",strArr[initial]+"");
if(initial==len-1){
System.out.println("Longest substring is::" + bm);
break;
}
}
else if(isPresent){
System.out.println("Longest substring is::" + bm);
bm.delete(0, bm.length());
++dinitial;
initial--;
hm.clear();
}
initial++;
}
else
{
bm.append(strArr[initial]);
hm.put(strArr[initial]+"",strArr[initial]+"");
initial++;
}
}
hm.clear();
}

Categories

Resources