Actually this tread is continuing from the other one. There wasn't enough characters to continue there. Anyway. the problem is that the output is "1(10) 2(23) 3(29)". Even though I could return string for the array values (10,23,29) and used string reference as 1, 2 and 3. My question is it possible to return index values 1,2,3 and as well as array values. Am I making an sense. Here is what I have done...
// int[] groups = {10, 23, 29}; in the constructor
String tempA = "";
String tempB = " ";
int[] temp = new int[4];
int length = groups.length;
for (int j = 0; j < length; j++)
{
temp[j] = groups[j];
tempB = tempB + "("+goups+")";
}
groups = temp;
Arrays.sort(coingroups);
for(int i = 1; i < groups.length;i++)
{
tempA = tempA+" "+(i)+ "("+groups[i]+")";
}
return tempA;
With the below code you are creating a string that and this string represents the whole array. Yet it will be harder to work with then just using the array 'groups'
// int[] groups = {10, 23, 29}; in the constructor
String tempA = "";
for (int j = 0; j < groups.length; j++)
{
tempA = tempA + " " + j + " (" + groups[j] + ") ";
}
return tempA;
If you create a Map, and save your data in there, you can get any information you want. Like:
Map<Integer, String> stack = new HashMap<Integer, String>();
stack.put(1, "10");
stack.put(2, "23");
stack.put(3, "29");
After storing everything, you can get the values of the Map by its key or value. Example:
stack.get(1) will return "10"
stack.get("10") will return 1
Related
City[] array = new City[6];
String [] arr = {"Paris","London","Rome","Los Angeles","New York","San Francisco"};
int [] arr2 = {200000, 100000, 80000, 60000, 50000, 45000};
String [] arr3 = {"Breitzel", "Statute of Liberty", "Tramways"};
for (int i = 0; i < 6; i++){
if (i<3){
City V = new City (arr[i], "EU", tab2[i]);
array[i] = V;
}
else {
for (int j = 0; j < 3; j++){
Capitale C = new Capitale (arr[i], "USA", arr2[i], arr3[j]);
array[i] = C;
}
}
}
The first incrementing loop works well, the one that creates cities (System.out.printline shows that City[] get 6 elements, which are the 6 cities.
BUT : the 3 American cities should each be assigned an element of arr3. This doesn't work. j doesn't get incremented and all 3 American cities get "Tramways".
I don't see why...
On the contrary, j is being incremented.
But each iteration of the internal loop is overwriting the results of the prior iteration.
The last iteration has j = 2, and arr3[2] is "Tramways".
I think you'll get the result you're looking for with this.
for (int i = 0; i < 6; i++){
if (i<3){
City V = new City (arr[i], "EU", tab2[i]);
array[i] = V;
}
else {
Capitale C = new Capitale (arr[i], "USA", arr2[i], arr3[j - 3]);
array[i] = C;
}
}
That said, the code isn't all that clear. The magic value of 3 isn't clear.
You could address this with a named constant:
final int INDEX_OF_FIRST_CAPITALE = 3;
Or by having arr3 be parallel to the other two arrays
String [] arr3 = { null, null, null, "Breitzel", "Statute of Liberty", "Tramways"};
Or by using a map from capital name to attraction.
Map<String,String> = new HashMap<String,String>();
This is my code, but I know this is not right. I have written a lot of code for such a simple task.
Sample input is:
welcome
Sample output is:
com
elc
lco
ome
wel
It should print:
your first string is 'com'
and
your last string is 'wel'
Code:
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int k = sc.nextInt();
int k1 = k;
int j = 0;
int t = str.length();
String [] s = new String [1000];
for (int i = t, a = 0; i >= k; i--, a++) {
s[a] = str.substring(j, k1);
j++;
k1++;
}
String[] s1 = new String[j];
for (int i = 0 ; i < j; i++) {
s1[i] = s[i];
}
for (int y = 0; y < j; y++) {
for (int z = y + 1; z < j; z++) {
if(s1[z].compareTo(s1[y]) < 0) {
String temp = s1[z];
s1[z] = s1[y];
s1[y] = temp;
}
}
}
System.out.println(s1[0]);
System.out.println(s1[1]);
}
}
Note: I split my strings, but I'm not able to arrange strings in alphabetical order, and feel that I have used a lot of arrays. Is there a better way to do this?
You can
reduce the number of variables,
use collections (list in this case) instead of Arrays to avoid having to set a size (1000)
Sort using the framework
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int k = sc.nextInt();
List<String> cutStrings = new ArrayList<String>();
for (int i = 0; i < str.length() - k; i++) {
cutStrings.add(str.substring(i, i + k));
}
Collections.sort(cutStrings);
System.out.println(cutStrings.get(0));
System.out.println(cutStrings.get(cutStrings.size()-1));
}
You can easily sort your String[] array by simply using
Arrays.sort(s);
This will sort your strings in the default order. If you need any other kind of order you can pass the comparator as a second parameter.
You can get first and last by getting s[0] and s[s.length-1]
I did a quick implementation of your requirements. It might not be exactly what you're looking for but it should get you started. :)
So, I used an ArrayList to grab the substrings and the use the Collections library to do the sorting for me. This is just one of the many ways of solving the problem, btw. The input word can vary in size so I felt that a list would be appropriate for this situation.
String s = "welcome";
List<String> words = new ArrayList<String>();
for (int i = 0; i < s.length() - 2; i++) {
String chunk = s.charAt(i) + "" + s.charAt(i + 1) + ""
+ s.charAt(i + 2);
words.add(chunk);
System.out.println(chunk);
}
Collections.sort(words);
System.out.println(words.toString());
Feel free to let me know if you have any questions or if I have made a mistake in the code.
Good luck!
Actual problem of your code is splitting. Sorting will work. If j value 1 and k1 value 3 then wel substring is coming. Next loop, (after incrementation of both j and k1 by 1) j value 2 and k1 value 4 then elc substring is coming, etc.
So, instead of
String [] s = new String [1000];
for (int i = t, a = 0; i >= k; i--, a++) {
s[a] = str.substring(j, k1);
j++;
k1++;
}
use
int k = sc.nextInt();
String [] s = new String [(str.length()/3)+1] ;
for ( int i = 0,a = 0; i<(str.length()-k); i+=k,a++)
{
s[a] = str.substring(i,(i+k));
System.out.println(s[a]);
}
s[s.length-1]=str.substring((str.length()-k),str.length());//to add remaining values
Arrays.sort(s);//sorting alphabatically
for(int i = 0; i < s.length; i++)
System.out.println(s[i]);
}
i value will be incremented by 3. In the for loop (i+=k) where k=3.
Output:
amp
com
e s
ple
wel
My task is to create a static method named "dupWords" that gets a strings as a parameter and returns how many times a word is at the same string. Now the catch is, that I need to return it as a Two-dimensional array, that have 2 columns and the rows will be how many different sub strings are in the string...
for example: "abcd xyz abcd abcd def xyz"
this will be the pairs [0][3] [5][2] [19][01] the first pair means that the word "abcd" appears 3 times and state at the index 0 (and you get the rest..)
this is an image of the two-dimensional array: (the text is in hebrew but you can see the drawing)
I started something...you will probably think its way off :/ (its just some start)
I think I didn't really understand how to deal with the two-dimensional array..
public static int[][] dupWords (String str) {
String [] stringArray = str.split(" ");
int countWords = 0;
int index = 0;
int [][] retArr;
for (int i = 0; i < stringArray.length; i++) {
for (int j = 0; j < stringArray.length; j++) {
if (stringArray[i].equalsIgnoreCase(stringArray[j])){
countWords++;
index = stringArray[i].indexOf(str);
}
}
}
}
Please help,
thankss
Find the number of unique words.
You can do it, by putting all the words from the stringArray to a hashmap. The hashmap will come handy later.
Create an array like that retArr = new int[unique][2];
Complete solution below (beware, I didn't even compile it!)
public static int[][] dupWords (String str) {
String [] stringArray = str.split(" ");
int countWords = 0;
int index = 0;
HashMap<String, Integer> indexMap = new HashMap<String, Integer>();
HashMap<String, Integer> countMap = new HashMap<String, Integer>();
int index = 0;
for (int i = 0; i < stringArray.size(); i++) {
String s = stringArray[i];
if (!indexMap .containsKey(s)) {
indexMap.put(s, index);
countMap.put(s, 1);
}
else {
int cnt = countMap.get(s);
countMap.put(s, cnt+1);
}
index += s.length() + 1;
}
int [][] retArr = new int[map.size()][2];
for (int i = 0; i < stringArray.size(); i++) {
String s = stringArray[i];
retArr[i][0] = indexMap.get(s);
retArr[i][1] = countMap.get(s);
}
return retArr;
}
Now, without HashMap, or any other dynamic structure it's quite difficult to do. The easiest approach is to create a bigger than necessary array and at the end trim it. This could look like this.
public static int[][] dupWords (String str) {
String [] stringArray = str.split(" ");
int countWords = 0;
int index = 0;
int [][] retArr = new int[stringArray.size()][2];
int uniqeWords = 0;
for (int i = 0; i < stringArray.size(); i++) {
String s = stringArray[i];
if (s != null) {
retArr[uniqueWords][0] = str.indexOf(s);
int cnt = 1;
for (int j = i + 1; j < stringArray.size(); j++) {
if (s.equalsIgnoreCase(stringArray[j])) {
stringArray[j] = null;
cnt++;
}
}
retArr[uniqueWords][1] = cnt;
uniqueWords++;
}
}
int[][] newRetArr = new int[uniqueWords][2];
for (int i = 0; i < uniqueWords; i++) {
newRetArr[i][0] = retArr[i][0];
newRetArr[i][1] = retArr[i][1];
}
return newRetArr;
}
Use a HashMap to store the count and first index of each unique word.
Map<String, Map<String, int>> uniqueWords = new HashMap<>();
Then Change your loop through stringArray to only use the first outer loop. You don't need the inner loop.
In each iteration through stringArray, do
if(!uniqueWords.get(stringArray[i])) {
uniqueWords.put(stringArray[i], new HashMap<String, int>());
uniqueWords.get(stringArray[i]).put("Count", 0);
uniqueWords.get(stringArray[i]).put("Index", str.indexOf(stringArray[i]));
}
uniqueWords.get(stringArray[i]).get("Count")++;
You can then use the uniqueWords map to build your return array. I'll leave that for you to code.
I'm not sure why the hashmap is printing out different things inside this while loop and outside of the while loop. I declared the map outside the while loop, so I assumed that it should be the same inside and outside. In the code, I have the same print statement inside the while loop and outside of it, but they are printing different things. The key for the map is personCounter, which increments and should be unique. Would really appreciate your help.
public Map<Integer, double[]> setRating(CSVReader r, int taskNum, int taskWeightNumHeader)
throws NumberFormatException, IOException {
String[] line;
int personCounter = 0;
Map<Integer, double[]> indivTaskRating = new HashMap<Integer, double[]>();
while ((line = r.readNext()) != null) {
double[] perTaskWeight = new double[5];
personCounter++;
int multiplier = taskNum * 5;
perTaskWeight[2] = Double.parseDouble(line[taskWeightNumHeader + multiplier]);
perTaskWeight[1] = Double.parseDouble(line[taskWeightNumHeader + multiplier + 1]);
perTaskWeight[0] = Double.parseDouble(line[taskWeightNumHeader + multiplier + 2]);
perTaskWeight[3] = Double.parseDouble(line[taskWeightNumHeader + multiplier + 3]);
perTaskWeight[4] = Double.parseDouble(line[taskWeightNumHeader + multiplier + 4]);
indivTaskRating.put(personCounter, perTaskWeight);
for (int j = 0; j < 5; j ++) {
System.out.println("personID: " +1+ ", rating: " +indivTaskRating.get(1)[j]);
}
}
for (int j = 0; j < 5; j ++) {
System.out.println("personID: " + 1+ ", rating: " +indivTaskRating.get(1)[j]);
}
return indivTaskRating;
}
You are using the same double array in every entry you place in the map. At the end it will be populated with the same values for each entry!
You need to reallocate the array on each iteration of your while loop to fix the problem.
while ((line = r.readNext()) != null) {
double[] perTaskWeight = new double[5];
// ....
}
You keep reusing the same array, so you actually overwrite its content at each loop (while).
You need to create a new instance (double[] perTaskWeight = new double[5];) within the while loop.
I'm trying to resolve all the combinations of elements based on a given string.
The string is like this :
String result="1,2,3,###4,5,###6,###7,8,";
The number of element between ### (separated with ,) is not determined and the number of "list" (part separated with ###) is not determined either.
NB : I use number in this example but it can be String too.
And the expected result in this case is a string containing :
String result = "1467, 1468, 1567, 1568, 2467, 2468, 2567, 2568, 3467, 3468, 3567, 3568"
So as you can see the elements in result must start with an element of the first list then the second element must be an element of the second list etc...
From now I made this algorithm that works but it's slow :
String [] parts = result.split("###");
if(parts.length>1){
result="";
String stack="";
int i;
String [] elmts2=null;
String [] elmts = parts[0].split(",");
for(String elmt : elmts){ //Browse root elements
if(elmt.trim().isEmpty())continue;
/**
* This array is used to store the next index to use for each row.
*/
int [] elmtIdxInPart= new int[parts.length];
//Loop until the root element index change.
while(elmtIdxInPart[0]==0){
stack=elmt;
//Add to the stack an element of each row, chosen by index (elmtIdxInPart)
for(i=1 ; i<parts.length;i++){
if(parts[i].trim().isEmpty() || parts[i].trim().equals(","))continue;
String part = parts[i];
elmts2 = part.split(",");
stack+=elmts2[elmtIdxInPart[i]];
}
//rollback i to previous used index
i--;
if(elmts2 == null){
elmtIdxInPart[0]=elmtIdxInPart[0]+1;
}
//Check if all elements in the row have been used.
else if(elmtIdxInPart[i]+1 >=elmts2.length || elmts2[elmtIdxInPart[i]+1].isEmpty()){
//Make evolve previous row that still have unused index
int j=1;
while(elmtIdxInPart[i-j]+1 >=parts[i-j].split(",").length ||
parts[i-j].split(",")[elmtIdxInPart[i-j]+1].isEmpty()){
if(j+1>i)break;
j++;
}
int next = elmtIdxInPart[i-j]+1;
//Init the next row to 0.
for(int k = (i-j)+1 ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i-j]=next;
}
else{
//Make evolve index in current row, init the next row to 0.
int next = elmtIdxInPart[i]+1;
for(int k = (i+1) ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i]=next;
}
//Store full stack
result+=stack+",";
}
}
}
else{
result=parts[0];
}
I'm looking for a more performant algorithm if it's possible. I made it from scratch without thinking about any mathematical algorithm. So I think I made a tricky/slow algo and it can be improved.
Thanks for your suggestions and thanks for trying to understand what I've done :)
EDIT
Using Svinja proposition it divide execution time by 2:
StringBuilder res = new StringBuilder();
String input = "1,2,3,###4,5,###6,###7,8,";
String[] lists = input.split("###");
int N = lists.length;
int[] length = new int[N];
int[] indices = new int[N];
String[][] element = new String[N][];
for (int i = 0; i < N; i++){
element[i] = lists[i].split(",");
length[i] = element[i].length;
}
// solve
while (true)
{
// output current element
for (int i = 0; i < N; i++){
res.append(element[i][indices[i]]);
}
res.append(",");
// calculate next element
int ind = N - 1;
for (; ind >= 0; ind--)
if (indices[ind] < length[ind] - 1) break;
if (ind == -1) break;
indices[ind]++;
for (ind++; ind < N; ind++) indices[ind] = 0;
}
System.out.println(res);
This is my solution. It's in C# but you should be able to understand it (the important part is the "calculate next element" section):
static void Main(string[] args)
{
// parse the input, this can probably be done more efficiently
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
int[] indices = new int[N];
for (int i = 0; i < N; i++)
length[i] = lists[i].Split(',').Length - 1;
string[][] element = new string[N][];
for (int i = 0; i < N; i++)
{
string[] list = lists[i].Split(',');
element[i] = new string[length[i]];
for (int j = 0; j < length[i]; j++)
element[i][j] = list[j];
}
// solve
while (true)
{
// output current element
for (int i = 0; i < N; i++) Console.Write(element[i][indices[i]]);
Console.WriteLine(" ");
// calculate next element
int ind = N - 1;
for (; ind >= 0; ind--)
if (indices[ind] < length[ind] - 1) break;
if (ind == -1) break;
indices[ind]++;
for (ind++; ind < N; ind++) indices[ind] = 0;
}
}
Seems kind of similar to your solution. Does this really have bad performance? Seems to me that this is clearly optimal, as the complexity is linear with the size of the output, which is always optimal.
edit: by "similar" I mean that you also seem to do the counting with indexes thing. Your code is too complicated for me to go into after work. :D
My index adjustment works very simply: starting from the right, find the first index we can increase without overflowing, increase it by one, and set all the indexes to its right (if any) to 0. It's basically counting in a number system where each digit is in a different base. Once we can't even increase the first index any more (which means we can't increase any, as we started checking from the right), we're done.
Here is a somewhat different approach:
static void Main(string[] args)
{
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
string[][] element = new string[N][];
int outCount = 1;
// get each string for each position
for (int i = 0; i < N; i++)
{
string list = lists[i];
// fix the extra comma at the end
if (list.Substring(list.Length - 1, 1) == ",")
list = list.Substring(0, list.Length - 1);
string[] strings = list.Split(',');
element[i] = strings;
length[i] = strings.Length;
outCount *= length[i];
}
// prepare the output array
string[] outstr = new string[outCount];
// produce all of the individual output strings
string[] position = new string[N];
for (int j = 0; j < outCount; j++)
{
// working value of j:
int k = j;
for (int i = 0; i < N; i++)
{
int c = length[i];
int q = k / c;
int r = k - (q * c);
k = q;
position[i] = element[i][r];
}
// combine the chars
outstr[j] = string.Join("", position);
}
// join all of the strings together
//(note: joining them all at once is much faster than doing it
//incrementally, if a mass concatenate facility is available
string result = string.Join(", ", outstr);
Console.Write(result);
}
I am not a Java programmer either, so I adapted Svinja's c# answer to my algorithm, assuming that you can convert it to Java also. (thanks to Svinja..)