Increment instance name - for-loop

Is there a way to effectively increment a instance name in, for example, a for-loop, like this?
for (int i=0; i<10; i++) {
City city+i = new City();
}
That code obviously does not work, but what can I do to create 10 objects, named City0, City1, City2 etc?

You can add the cities to a list or an array and access them by index. Example of list approach in Java:
List<City> cities = new ArrayList<>();
for (int i = 0; i < 10; i++) {
cities.add(new City());
}
Then, you access it like city.get(0) for first one city.get(1) for second etc.

City city[10]; // declare an array of "City" objects, 10 in size
for(int i = 0; i < 10; i++){
city[i] = new City(); //changed to an array
}

Related

Why won't my random selection without replacement algorithm work?

I have made a very simple algorithm that picks a set of numToPick random numbers from the range 0 to batchMax, without replacement. Then it places each selected number in an array called numsPicked. For some reason I cannot explain, it isn't working on DartPad.
import 'dart:math';
void main() {
print(randNoReplace(2, 9));
}
List<int> randNoReplace(int numToPick, int batchMax) {
List<int> numsPicked = List(numToPick);
List<int> tmpArray = List(batchMax);
//this for loop creates the tmpArray from 0 to batchMax.
for (int i = 0; i <= batchMax; i++) {
tmpArray[i] = i;
}
//this for loop randomly scrambles said tmpArray.
for (int i = 0; i <= batchMax; i++) {
int randIndex = Random().nextInt(batchMax);
int tmp = tmpArray[i];
tmpArray[i] = tmpArray[randIndex];
tmpArray[randIndex] = tmp;
}
//finally, this for loop adds the first numToPick entries of the scrambled tmpArray and adds them to numsPicked.
for (int i = 0; i < numToPick; i++) {
numsPicked[i] = tmpArray[i];
}
return numsPicked;
}
So, for example, with 2 and 9 respectively, this algorithm should theoretically give me 2 random non-duplicate numbers in the range [0, 9].
I think the main issue in your code is that your first two for-loops are going from 0 to
batchMax including batchMax. This is a problem since you are using batchMax to specify the size of your tmpArray. Since the index of a List starts at 0, we cannot ask for the batchMax-element but at most batchMax - 1.
So you code should properly be (or `tmpArray should be one element bigger):
import 'dart:math';
void main() {
print(randNoReplace(2, 9));
}
List<int> randNoReplace(int numToPick, int batchMax) {
List<int> numsPicked = List(numToPick);
List<int> tmpArray = List(batchMax);
//this for loop creates the tmpArray from 0 to batchMax.
for (int i = 0; i < batchMax; i++) {
tmpArray[i] = i;
}
//this for loop randomly scrambles said tmpArray.
for (int i = 0; i < batchMax; i++) {
int randIndex = Random().nextInt(batchMax);
int tmp = tmpArray[i];
tmpArray[i] = tmpArray[randIndex];
tmpArray[randIndex] = tmp;
}
//finally, this for loop adds the first numToPick entries of the scrambled tmpArray and adds them to numsPicked.
for (int i = 0; i < numToPick; i++) {
numsPicked[i] = tmpArray[i];
}
return numsPicked;
}
Some other minor comments:
You should properly not initialize a new Random() object each time you need a random number. Instead, you should create one instance and reuse it.
Your code are not making much use of the Dart SDK. In fact, your code could properly be simplified into:
void main() {
print(randNoReplace(2, 9));
}
List<int> randNoReplace(int numToPick, int batchMax) =>
(List.generate(batchMax, (index) => index)..shuffle())
.sublist(0, numToPick);

Create Random Number List With No Repetition

I'm looking to create a list of 'random' numbers from 1 to 15 but without any repetition. I have created an array and looking to store each number in it but can't figure out how to do this. I've gotten as far as creating the random list and storing them in the array but can't quite get to ensure there are no repetitions. Any help would be appreciated. My code is as follows:
int[] myList = new int[15];
Random random = new Random();
for (int i = 0; myList.Length; i++)
{
myList[i] = random.Next(1, 15);
}
Because the size of your list is equal to the possible values, you can just create the list in normal order:
int[] myList = new int[15];
for (int i = 0; i < myList.Length; i++)
{
myList[i] = i + 1;
}
and then shuffle it, for example by assigning a random value to each entry and sort by that value:
Random random = new Random();
myList = myList.OrderBy(a => random.Next()).ToArray();
You can do it using Fisher–Yates shuffle.
Sample Implementation:
int n = 15;
int[] myList = new int[n];
Random random = new Random();
for (int i = 0; i < n; i++)
{
myList[i] = i + 1;
}
for (int i = n - 1; i >= 1; i--)
{
int j = random.Next(1, i);
int temp=myList[i];
myList[i]=myList[j];
myList[j]=temp;
}
You need to get the algorithm right.
Start from i=15
Pick a random number from 1 to i.
Append it to the list.
Swap it with (i-1)th index.
Decrement i by 1.
Repeat the above steps.
The code for above can be:
int[] myList = new int[15];
int[] original_list = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
Random random = new Random();
for (int i = myList.Length; i>=0; i--)
{int randNo = random.Next(0, i-1);
myList[i] = original_list[randNo];
swap(original_list[i-1],original_list[randNo]); //your swap method
}

Nested loop complexity

I have several lists of varying size, each index of the list contains both a key and an object : list1.add('Key', obj).
The lists are all sorted.
My aim is to iterate through the list and match 1 or more items in list 2,3,4 or n to an item in the mainList using the key.
Currently I do something along the lines of:
for i to list1 size
for j to list2 size
if list1[i] = list2[j]
do stuff
As I loop through I'm, using boolean values to exit quickly using a if current != previous check and I'm deleting the object from the list I take it from.
it's working fine but I now have another list that I need to match and possible another n lists afterwards. The lists are of different sizes.
the 2 options that I can see are to either repeat the above segment of code several times where the inner list is changed - I do no like this approach.
The other option is to extend the above and once one inner loop is finished, move onto the next:
for i to list1 size
for j to list2 size
if list1[i] = list2[j]
do stuff
for k to list2 size
if list1[i] = list2[k]
do stuff
I'd like to think I'm correct in thinking that the 2nd is more efficient however I'm unsure. Also, is there a better way?
Thanks for any advice / help.
If the lists are all sorted then you only need to iterate though each list once; on each iteration of the main list, iterate through a secondary list (starting at the previously saved index, initialized to 0) until you find an index whose value is greater than the current value of the main list, save this index, and proceed to the next secondary list.
Array<Integer> indices = new Array(n-1); // indices for every list except list1
for(int i = 0; i < indices.size; i++) {
indices[i] = 0;
}
for(int i = 0; i < list1.size; i++) {
Value curVal = list1[i];
while(indices[0] < list2.size && list2[indices[0]] <= curVal) {
if(list2[indices[0]] == curVal) {
// do stuff on list2[indices[0]]
}
indices[0]++;
}
while(indices[1] < list3.size && list3[indices[1]] < curVal) {
if(list3[indices[1]] == curVal) {
// do stuff on list3[indices[1]]
}
indices[1]++;
}
// etc
}
You can avoid the copy-pasting by using something like a ListIterator that contains a list and its current index; then on each iteration of the main loop you'll iterate through a list of ListIterators in lieu of the copy-pasted code block
public class ListIterator {
int index = 0;
List<Value> list;
Value curVal() {
return list[index];
}
boolean hasNext() {
return (index < list.size);
}
}
List<ListIterator> iterators;
for(int i = 0; i < list1.size; i++) {
Value curVal = list1[i];
for(int j = 0; j < iterators.size; j++) {
ListIterator iterator = iterators[j];
while(iterator.hasNext() && iterator.curVal() <= curVal) {
if(iterator.curVal() == curVal) {
// do something with iterator.curVal()
}
iterator.index++;
}
}
}
This is time complexity O(n) where n is the sum of the lengths of all of your lists
Edit: If it's difficult to compare keys via <=, then you can use a Set implementation instead. Add the List1 keys to a Set, then iterate through the remaining lists testing for set membership.
Set<String> set = new Set(List1);
Array<List> lists = new Array();
// add lists to Array<List>
for(int i = 0; i < lists.size; i++) {
List currentList = lists[i];
for(int j = 0; j < currentList.size; j++) {
if(set.contains(currentList[j]) {
// do something
}
}
}

LINQ way to count elements in each value of dictionary?

I have a Dictionary<String, String[]> and I'm hoping for a LINQ way to count up all the strings in the values. Currently I'm using a good ol' fashioned for:
int total = 0;
for (int i = 0; i < dict.Count; i++) {
total += dict.ElementAt(i).Value.Length;
}
I was thinking of a Select() but then I'd have a IEnumerable<String[]> or basically a 2D array of strings. Is there a better way?
Sum1 should work for that
int total = dict.Sum(d => d.Value.Length);
Here is a full working demo you can test in linqpad or a console app if so inclined
Dictionary<string, string[]> dict = new Dictionary<string, string[]>();
for( int i = 0; i < 10; i++ )
{
dict["s"+i] = Enumerable.Range(0,10).Select(s => s.ToString()).ToArray();
}
int total = dict.Sum(d => d.Value.Length);
Console.Write(total);//100
1. MSDN: Enumerable.Sum Method
total=dict.Select(n=>n.Value.Lenght).Sum();

Creating a new JTable from current JTable view

I am working on a project that involves JTable and performing sorting and filtering operations on it. I am done with the sorting and filtering part and now I want to be able to create a new table from the current view of older table.
e.g. If I apply certain filters to my old table, some rows are filtered out. I don't want those filtered out rows in my new table. I figured that I can convert the new row indices to model indices and add the cell values manually to new table's model, but I was wondering if there's any other efficient way to do this?
Following is what I ended up doing:
//this code block will print out the rows in current view
int newRowCount = table.getRowCount();
int newColumnCount = table.getColumnCount();
for (int i = 0; i < newRowCount; i++) {
for (int j = 0; j < newColumnCount; j++) {
int viewIndex = table.convertRowIndexToModel(i);
String value = (String) model.getValueAt(viewIndex, j);
System.out.print(value + "\t");
}
System.out.println();
}
no need for any index conversion, simply ask query the table instead of the underlying model
for (int i = 0; i < table.getRowCount(); i++) {
for (int j = 0; j < table.getColumnCount(); j++) {
Object value = table.getValueAt(i, j);
System.out.print(value + "\t");
}
}
Note: better rename the i/j to row/column for readability, was too lazy ;-)

Resources