I need to create a Map like data structure using an Array or ArrayLists.
Quick program over view: My map holds objects of Word which is a string and holds a frequency count of how many times the word appears in a next file.
Here is code for MyMap, Program outputs nothing.
List<Word>[] table;
int tableSize;
int index;
public MyMap(int tableSize){
table = new ArrayList[tableSize];
this.tableSize = tableSize;
}
//Problem!!
public void put(Word w){
index = Math.abs(w.hashCode()) % tableSize;
if(table[index].isEmpty()){
table[index].add(w);
}
else{
w.increaseFreq();
table[index].set(index, w);
}
}
public void displayMap(){
for(List<Word> w: table){
System.out.println(w);
}
}
}
How about using either a Generic.Dictionary<string,Word> or a KeyedCollection<string,Word>?
If you use the KeyedCollection then you will need to inherit from it and provide a GetKeyForItem implementation.
Related
For example, string "AAABBB" will have permutations:
"ABAABB",
"BBAABA",
"ABABAB",
etc
What's a good algorithm for generating the permutations? (And what's its time complexity?)
For a multiset, you can solve recursively by position (JavaScript code):
function f(multiset,counters,result){
if (counters.every(x => x === 0)){
console.log(result);
return;
}
for (var i=0; i<counters.length; i++){
if (counters[i] > 0){
_counters = counters.slice();
_counters[i]--;
f(multiset,_counters,result + multiset[i]);
}
}
}
f(['A','B'],[3,3],'');
This is not full answer, just an idea.
If your strings has fixed number of only two letters I'll go with binary tree and good recursion function.
Each node is object that contains name with prefix of parent name and suffix A or B furthermore it have numbers of A and B letters in the name.
Node constructor gets name of parent and number of A and B from parent so it needs only to add 1 to number of A or B and one letter to name.
It doesn't construct next node if there is more than three A (in case of A node) or B respectively, or their sum is equal to the length of starting string.
Now you can collect leafs of 2 trees (their names) and have all permutations that you need.
Scala or some functional language (with object-like features) would be perfect for implementing this algorithm. Hope this helps or just sparks some ideas.
Since you actually want to generate the permutations instead of just counting them, the best complexity you can hope for is O(size_of_output).
Here's a good solution in java that meets that bound and runs very quickly, while consuming negligible space. It first sorts the letters to find the lexographically smallest permutation, and then generates all permutations in lexographic order.
It's known as the Pandita algorithm: https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
import java.util.Arrays;
import java.util.function.Consumer;
public class UniquePermutations
{
static void generateUniquePermutations(String s, Consumer<String> consumer)
{
char[] array = s.toCharArray();
Arrays.sort(array);
for (;;)
{
consumer.accept(String.valueOf(array));
int changePos=array.length-2;
while (changePos>=0 && array[changePos]>=array[changePos+1])
--changePos;
if (changePos<0)
break; //all done
int swapPos=changePos+1;
while(swapPos+1 < array.length && array[swapPos+1]>array[changePos])
++swapPos;
char t = array[changePos];
array[changePos] = array[swapPos];
array[swapPos] = t;
for (int i=changePos+1, j = array.length-1; i < j; ++i,--j)
{
t = array[i];
array[i] = array[j];
array[j] = t;
}
}
}
public static void main (String[] args) throws java.lang.Exception
{
StringBuilder line = new StringBuilder();
generateUniquePermutations("banana", s->{
if (line.length() > 0)
{
if (line.length() + s.length() >= 75)
{
System.out.println(line.toString());
line.setLength(0);
}
else
line.append(" ");
}
line.append(s);
});
System.out.println(line);
}
}
Here is the output:
aaabnn aaanbn aaannb aabann aabnan aabnna aanabn aananb aanban aanbna
aannab aannba abaann abanan abanna abnaan abnana abnnaa anaabn anaanb
anaban anabna ananab ananba anbaan anbana anbnaa annaab annaba annbaa
baaann baanan baanna banaan banana bannaa bnaaan bnaana bnanaa bnnaaa
naaabn naaanb naaban naabna naanab naanba nabaan nabana nabnaa nanaab
nanaba nanbaa nbaaan nbaana nbanaa nbnaaa nnaaab nnaaba nnabaa nnbaaa
I am trying to make like a Scoreboard but for a single player. I want to save my best 10 scores to the board and display it to the MainMenu. So far I know how to save and display only one result. The code is as follows:
[SerializeField] private int score;
void Update()
{
if (score > PlayerPrefs.GetInt("highestScore"))
{
PlayerPrefs.SetInt("highestScore", score);
}
}
And I am displaying as follows in my MainMenu scene
void Start()
{
highScore.text = PlayerPrefs.GetInt("highestScore").ToString();
}
Is it possible if you help me to save my last 10 best scores and display them? I couldn't find any tutorial on how to do that. I guess I should you array of Ints and loop through that array and then save it to PlayerPrefs but I have no idea how to do that. Hope you will be able to help me and thank you in advance!!
You could use ArrayPrefs2 to store as an array (http://wiki.unity3d.com/index.php/ArrayPrefs2), then update using:
static void UpdateHighScores(int newScore)
{
var highScores = PlayerPrefsX.GetIntArray("highScores");
if (newScore > highScores[0]) {
highScores[0] = newScore;
Array.Sort(highScores);
PlayerPrefsX.SetIntArray("highScores", highScores);
}
}
After initializing the PlayerPrefs key "highScores" somewhere else with:
PlayerPrefsX.SetIntArray("highScores", new Array[10]);
Note that this produces an array with the lowest high score first and the true highest score last in the array.
You can definitely save more keys,
PlayerPrefs
takes parameters one is a key and the second is a value
you can set it up like
PlayerPrefs.SetInt("highScore_1", value);
PlayerPrefs.SetInt("highScore_2", value);
PlayerPrefs.SetInt("highScore_3", value);
PlayerPrefs.SetInt("highScore_4", value);
PlayerPrefs.SetInt("highScore_5", value);
So when some one scores more than one of the previous highest score, what you'll do is
int newScore = 50;
for(int i=1; i <= 5; i++){
if(newScore > PlayerPrefs.GetInt("highScore_"+i)){
for(int x = 5; x > i; x--){
int value = PlayerPrefs.GetInt("highScore_"+(x-1));
PlayerPrefs.setInt("highScore_"+x, value);
}
break;
}
}
Let me know if it works.
I was curious to know if there is an efficient way to store data into a container that has a maximum amount of values and when that value is reached it start removing the oldest values in order to add new ones. And all this in an ordered fashion (meaning that new data should come after the last new data).
I know I could achieve this using a queue
q.Enqueue(1);
q.Enqueue(2);
q.Enqueue(3); // 1 2 3
q.Dequeue(); // 2 3
q.Enqueue(4); // 2 3 4
but in order to iterate through the data afterwards requires to transform the queue in an array, which I'm not sure how efficient it is.
Maybe it's better to have an array with a fixed size and have an index that shifts to the start when the array is full and using some modulo magic iterate always backwards to query the data from most recent to less recent. This would be less readable but working and more efficient I guess.
So my question would be, is there a better more readable and efficient way?
And also, what is the efficiency of using ToArray() when using other data structures (e.g. List, Queue, Stack..). When should this be avoided?
At the end I decided to implement my idea. Not sure if this is the best way, but it works well for my needs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DataHolder<T> : IEnumerable
{
private T[] _data;
private int _maxSize;
private int _currIdx;
private int _currSize;
public DataHolder(int size)
{
_maxSize = size;
_data = new T[_maxSize];
_currIdx = -1;
_currSize = 0;
}
public void Add(T data)
{
if (_currSize < _maxSize) _currSize++;
_currIdx = NioUtils.PositiveMod((_currIdx + 1), _maxSize);
_data[_currIdx] = data;
}
///<summary>
/// Gets the element at index. The 0 element is the last one added.
///</summary>
public T GetElementAt(int index)
{
if (index >= _currSize)
{
throw new System.ArgumentException("Index out of bounds exception.", "index");
}
int shiftIndex = NioUtils.PositiveMod((_currIdx - index), _maxSize);
return _data[shiftIndex];
}
/// Implement interface IEnumerable in order to iterate throught this object.
public IEnumerator GetEnumerator()
{
int count = 0;
int index = _currIdx;
while (count < _currSize)
{
count++;
yield return _data[index];
index = NioUtils.PositiveMod((index - 1), _maxSize);
}
}
}
Where PositiveMod is:
public static int PositiveMod(int value, int n)
{
int v = value % n;
return v >= 0 ? v : n + v;
}
In the constructor of an Array is there a guarantee that the init function will be called for the indexes in an increasing order?
It would make sense but I did not find any such information in the docs:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/-init-.html#kotlin.Array%24%28kotlin.Int%2C+kotlin.Function1%28%28kotlin.Int%2C+kotlin.Array.T%29%29%29%2Finit
There is no guarantee for this in the API.
TLDR: If you need the sequential execution, because you have some state that changes see bottom.
First lets have a look at the implementations of the initializer:
Native: It is implemented in increasing order for Kotlin Native.
#InlineConstructor
public constructor(size: Int, init: (Int) -> Char): this(size) {
for (i in 0..size - 1) {
this[i] = init(i)
}
}
JVM: Decompiling the Kotlin byte code for
class test {
val intArray = IntArray(100) { it * 2 }
}
to Java in Android Studio yields:
public final class test {
#NotNull
private final int[] intArray;
#NotNull
public final int[] getIntArray() {
return this.intArray;
}
public test() {
int size$iv = 100;
int[] result$iv = new int[size$iv];
int i$iv = 0;
for(int var4 = result$iv.length; i$iv < var4; ++i$iv) {
int var6 = false;
int var11 = i$iv * 2;
result$iv[i$iv] = var11;
}
this.intArray = result$iv;
}
}
which supports the claim that it is initialized in ascending order.
Conclusion: It commonly is implemented to be executed in ascending order.
BUT: You can not rely on the execution order, as the implementation is not guaranteed by the API. It can change and it can be different for different platforms (although both is unlikely).
Solution: You can initialize the array manually in a loop, then you have control about the execution order.
The following example outlines a possible implementation that has a stable initialisation with random values, e.g. for tests.
val intArray = IntArray(100).also {
val random = Random(0)
for (index in it.indices) {
it[index] = index * random.nextInt()
}
}
Starting from the version 1.3.50 Kotlin has guaranteed sequential array initialization order in its API documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/-init-.html
The function init is called for each array element sequentially starting from the first one. It should return the value for an array element given its index.
in this program i have used different array variable for each of
the fields in a
database.In database all fields having the same datatype and now i want to store all
the fields values into one array variable.is it possible???
import java.sql.*;
class ja1
{
public static void main(String ar[])
{
try
{
int x,i,j,k,l;
int a[]=new int[30];
int b[]=new int[30];
int c[]=new int[30];
int d[]=new int[30];
int count[]=new int[10];
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c1=DriverManager.getConnection("Jdbc:Odbc:ds");
Statement s=c1.createStatement();
ResultSet r=s.executeQuery("select * from pro");
i=0;
j=0;
k=0;
l=0;
x=0;
while(r.next())
{
a[i]=r.getInt(2);
i++;
b[j]=r.getInt(3);
j++;
c[k]=r.getInt(4);
k++;
d[l]=r.getInt(5);
l++;
}
for(i=0;i<6;i++)
System.out.println(""+a[i]);
for(j=0;j<6;j++)
System.out.println(""+b[j]);
System.out.print("\n\n");
for(k=0;k<6;k++)
System.out.println(""+c[k]);
System.out.print("\n\n");
for(l=0;l<6;l++)
System.out.println(""+d[l]);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
Yes, it is possible in several ways :
1) If you want to use only one array then please create an array with size of 120 (4X30) and use 4 counter to arrange your data in range. That means, your first variable would be from index 0 to 29, the 2nd would be from 30 to 69 and so on. This is not good if you don't know the exact size of your array as you are binding them with perfect size of 30.
2) You can create a POJO and have 4 arrays into it, you can use a List instead of array, but it depends on your implementation. So, create a class, put 4 arrays into it, give good variable names and access thru getter/setter methods. This will be a clear code
3) You can use a Map<Integer,Integer[]> or Map<Integer,List<Integer>> and have a single variable/reference which is holding your key value pair.
It all depends on you, if you dont know, why are you using arrays,then please move the Collection
I would define a POJO for the record and then use a generic list to add and iterate the record/s
Try this:
class RecordData
{
public int First;
public int Second;
public int Third;
public int Fourth;
}
class ja1
{
public static void main(String ar[])
{
try
{
List<RecordData> list = new ArrayList<RecordData>;
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection c1=DriverManager.getConnection("Jdbc:Odbc:ds");
Statement s=c1.createStatement();
ResultSet r=s.executeQuery("select * from pro");
while(r.next())
{
RecordData data = new RecordData();
data.First = r.getInt(2);
data.Second = r.getInt(3);
data.Third = r.getInt(4);
data.Fourth = r.getInt(5);
list.add(data);
}
for(RecordData data : list) {
System.out.println(data.First);
System.out.println(data.Second);
System.out.println(data.Third);
System.out.println(data.Fourth);
}
}
catch(Exception e)
{
System.out.print(e);
}
}
}