How do I shuffle a list? - list

How do I shuffle a List in Beef? I would like to add an extension to Random that shuffles a List in-place:
using System.Collections.Generic;
namespace System
{
extension Random
{
public virtual void Shuffle<T>(List<T> list)
{
// Use this to shuffle the list in-place
}
}
}

Use the Fisher-Yates shuffle algorithm:
using System.Collections.Generic;
namespace System
{
extension Random
{
public virtual void Shuffle<T>(List<T> list)
{
for (let i = list.Count - 1; i > 0; i--)
{
let j = Next(0, i + 1);
let tmp = list[j];
list[j] = list[i];
list[i] = tmp;
}
}
}
}

Related

How can I print a Dictionary in c++ ? This is the code that im running, and I cant get to work the printDicionary method

This is the code that im running, and I cant get to work the printDicionary method.
Im not sure how to use the vector i created and i want to know how could I print all of the elements in this way:
[0]:
[1]: (1501, “adiós”), (301, “nuevo”)
[2]:
[3]: (23, “perro”)
…
[5]: (15, “hola”)
…
[9]: (9, “gato”)
#include <iostream>
#include <vector>
using namespace std;
template <class K, class V>
class KeyPair{
public:
K key;
V value;
KeyPair(){
key=NULL;
value=NULL;
}
KeyPair(K key, V val){
this->key=key;
this->value=val;
}
};
template <class K, class V>
class Dictionary{
public:
vector<KeyPair<K,V> > *dict;
int positions;
Dictionary(){
positions=10;
dict=new vector<KeyPair<K,V> >[positions];
}
Dictionary(int pos){
positions=pos;
dict=new vector<KeyPair<K,V> >[positions];
}
void insert(K key, V value){
KeyPair<K,V> kp(key, value);
int hash=key%positions;
for(int i=0; i<dict[hash].size(); i++){
if(dict[hash][i].key==key){
cout<<"llave ya existente"<<endl;
return;
}
}
dict[hash].push_back(kp);
//dict//arreglo de vectores keypair
//dict[hash]//vector de keypair
}
V checkAtKey(K key){
int hash=key%positions;
for(int i=0; i<dict[hash].size(); i++){
if(dict[hash][i].key==key){
return dict[hash][i].value;
}
}
return NULL;
}
void printDictionary(){
This is where i created the method
for(int i=0; i<dict[i].size(); i++){
cout << dict.key <<endl;
Im not sure if this is the way i should call the dict
cout << dict.value <<endl;
return;
}
}
};
int main(){
Dictionary<int, string> a;
a.insert(5, "perro");
a.insert(4, "gato");
Dictionary<int, string> b;
b.insert(15, "lombriz");
b.printDictionary();
}
there are a lot of mistakes in your code, man.
the "kp" member of Dictionary is a pointer (it has that "*" star), so you must use "->" to access its members, such as ".at(i)", which is the same as [i], or ".push_back(i)" to add an element at the end of the vector.
i have put your original code in comments and replaced it with the right code so you can see what changes i made. ask me if you wanna know more about what i changed, bro. good luck!
#include <iostream>
#include <vector>
using namespace std;
template<class K, class V> class KeyPair
{
public:
K key;
V value;
KeyPair()
{
key = NULL;
value = NULL;
}
KeyPair(K key, V val)
{
this->key = key;
this->value = val;
}
};
template<class K, class V> class Dictionary
{
public:
vector<KeyPair<K,V>> * dict;
int positions;
Dictionary()
{
positions = 10;
dict = new vector<KeyPair<K, V>>[positions];
}
Dictionary(int pos)
{
positions = pos;
dict = new vector<KeyPair<K, V>>[positions];
}
void insert(K key, V value)
{
KeyPair<K, V> kp(key, value);
//int hash = key % positions;
//for (int i = 0; i < dict[hash].size(); i++)
for (int i = 0; i < dict->size(); i++)
{
//if (dict[hash][i].key == key)
if (dict->at(i).key == key)
{
cout << "llave ya existente" << endl;
return;
}
}
//dict[hash].push_back(kp);
dict->push_back(kp);
}
V checkAtKey(K key)
{
//int hash = key % positions;
//for (int i = 0; i < dict[hash].size(); i++)
for (int i = 0; i < dict->size(); i++)
{
//if (dict[hash][i].key == key)
if (dict->at(i).key == key)
{
//return dict[hash][i].value;
return dict->at(i).value;
}
}
return NULL;
}
void printDictionary()
{
//for (int i = 0; i < dict[i].size(); i++){
for (int i = 0; i < dict->size(); i++)
{
// cout << dict.value << endl;
KeyPair<K, V> curr_key = dict->at(i);
printf("%d - %s\n", curr_key.key, curr_key.value.c_str());
// or you can do this
// std::cout << curr_key.key << " - " << curr_key.value.c_str();
}
}
};
int main()
{
Dictionary<int, string> a;
a.insert(5, "perro");
a.insert(4, "gato");
Dictionary<int, string> b;
b.insert(15, "lombriz");
b.printDictionary();
return 0;
}

C++ Bubble sort dynamically allocated array

I wrote a bubble sorting algorithm which sorts a dynamically allocated array using string comparison.
Here is my code:
void AddressBook::bubble_sort_address_book(){
bool swapped = true;
while(swapped){
swapped = false;
for(int i = 0; i < noOfEmployees; i++){
if(employees[i].combined_name() > employees[i+1].combined_name()){
Employee temp_employee = employees[i+1];
employees[i+1] = employees[i];
employees[i] = temp_employee;
}
}
}
}
My problem is pretty obvious, yet I can not seem to figure out how to solve it: The code sometimes fails on the line (in an undefined manner) :
Employee temp_employee = employees[i+1]
Its pretty obvious because if i is equal to the end of the array, accessing memory with i+1 results in undefined behaviour. However, if I stop the for loop with noOfEmployees-1, this does not happen but the first element is never sorted (obviously).
How can I implement bubble sort properly? It seems as such a trivial task. Am I missing something?
The following simplified version in pure C works fine:
int employees[10]= {3,1,7,6,9,7,1,0,2,6};
int noOfEmployees= 10;
void bubble_sort_address_book(void){
bool swapped = true;
int i;
while(swapped){
swapped = false;
for(i = 0; i < noOfEmployees-1; i++){
if(employees[i] > employees[i+1]){
int temp_employee = employees[i+1];
employees[i+1] = employees[i];
employees[i] = temp_employee;
swapped= true;
}
}
}
}
int main()
{
int i;
bubble_sort_address_book();
for (i=0; i<noOfEmployees; i++) {
printf("emp %d= %d\n", i, employees[i]);
}
return 0;
}
As you request, the function of variable swapped is to indicate that following a complete pass through the array no swap occurred and so it indicates the array is now sorted.
You can use an explicit bound on the outer loop.
You should also split things out into smaller functions.
bool operator <(Employee const & lhs, Employee const & rhs) {
return lhs.combined_name() < rhs.combined_name();
}
// a.k.a. std::swap
void swap(Employee & lhs, Employee & rhs) {
Employee temp(static_cast<Employee&&>(lhs)); // a.k.a. std::move
lhs = static_cast<Employee&&>(rhs);
rhs = static_cast<Employee&&>(temp);
}
void bubble_sort_impl(Employee * begin, Employee * end) {
for (; end != begin; --end) {
for (Employee * it = begin; it+1 != end; ++it) {
if (*(it+1) < *it) {
swap(*it, *(it+1));
}
}
}
}
// do we really need "bubble_" or "_address_book" in this name?
void AddressBook::bubble_sort_address_book() {
bubble_sort_impl(employees, employees + noOfEmployees);
}
another solution:
#include <iostream>
#include <vector>
using namespace std;
int employees[10] = { 3,1,7,6,9,7,1,0,2,6 };
void bubble_sort_address_book(void) {
bool swapped = true;
int i;
int noOfEmployees = 10;
while (swapped) {
swapped = false;
for (i = 1; i <= noOfEmployees ; i++) {
if (employees[i] > employees[i - 1]) {
int temp_employee = employees[i - 1];
employees[i - 1] = employees[i];
employees[i] = temp_employee;
swapped = true;
}
}
}
}
int main()
{
int i;
int noOfEmployees = 10;
bubble_sort_address_book();
for (i = 0; i<noOfEmployees; i++) {
printf("emp %d= %d\n", i, employees[i]);
}
return 0;
}

Autocomplete using Trie

I'm attempting to make some sort of autocomplete feature in c++. First by using a Trie and once that works (and most importantly, I know HOW it all works) I'll try it using a Ternary tree. But as for now I get a segmentation fault when ever I add words starting with a different characte than those already in the Trie.
Eg. we add "abc", "abcd" and "abcde" this is no problem. Later when I want to add (while the "abc" etc are still in the Trie) "xfce", "xfced" a segmentation fault occurs.
I've been debugging this for some while now and can't seem to find the problem.
I think the problem resides somewhere in Trie.cpp so that's the file I'll provide here. However it might be in the main function aswell but I don't wanna get yelled at for posting to much code...
#include "Trie.h"
#include <iostream>
Trie::Trie()
{
this->root = new Node(false);
}
Trie::~Trie()
{
}
Trie::Node::Node(bool isLeaf)
{
this->isLeaf = isLeaf;
}
void Trie::insert(const std::string& word)
{
Node* crawler = this->root;
int index;
for(int i = 0; i < word.length(); ++i)
{
index = CHAR_TO_INDEX(word.at(i));
if(!crawler->children[index])
{
crawler->children[index] = new Node(false);
}
crawler = crawler->children[index];
}
crawler->isLeaf = true;
}
int Trie::contains(const std::string& word)
{
int index;
Node* crawler = this->root;
for(int i = 0; i < word.length(); ++i)
{
index = CHAR_TO_INDEX(word.at(i));
if(!crawler->children[index])
{
return -1;
}
crawler = crawler->children[index];
}
return (crawler != NULL && crawler->isLeaf);
}
std::vector<std::string> Trie::possibleSuffixes(std::string& prefix)
{
Node* crawler = this->root;
int index;
std::vector<std::string> result;
for(int i = 0; i < prefix.length(); ++i)
{
index = CHAR_TO_INDEX(prefix.at(i));
crawler = crawler->children[index];
}
traverse(prefix, crawler, result);
return result;
}
void Trie::traverse(std::string prefix, Node* node, std::vector<std::string>& v)
{
if(node->isLeaf)
{
v.push_back(prefix);
}
for(int i = 0; i < ALPHABET; ++i)
{
if(node->children[i])
{
traverse(prefix + (char)('a' + i), node->children[i], v);
}
}
}
Entire Trie class:
#ifndef TRIE_H
#define TRIE_H
#include <string>
#include <vector>
#define ARRAYSIZE(a) sizeof(a / sizeof(a[0]))
#define ALPHABET 26
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
class Trie
{
private:
struct Node
{
Node(bool isLeaf);
struct Node *children[ALPHABET];
bool isLeaf;
};
Node *root;
void traverse(std::string prefix, Node* node, std::vector<std::string>& v);
public:
Trie();
~Trie();
int contains(const std::string& word); //Checks the existance of a specific word in the trie
void insert(const std::string& word); //Inserts new word in the trie if not already there
std::vector<std::string> possibleSuffixes(std::string& prefix);
};
Though you didn't mention about your Node class, I am assuming this -
class Node {
public:
bool isLeaf;
// must be >= 25 as you're inserting lowercase letters
// assuming your CHAR_TO_INDEX(ch) returns 0 based index
// e.g. 'a' => 0, 'b' => 1 ... 'z' => 25
Node* children[30];
// default constructor should be like this
Node(): isLeaf(false) {
for(int i = 0; i < 26; i++) {
children[i] = NULL;
}
}
~Node() {
for(int i = 0; i < 26; i++) {
if(children[i]) {
delete children[i];
children[i] = NULL;
}
}
delete this;
}
};
Please compare your Node class/struct whether its something like this.

C++ Remove duplication in a set of list

I'm trying to remove duplications in the return list in this question
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
All numbers (including target) will be positive integers.
Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
The solution set must not contain duplicate combinations.
For example, given candidate set 10,1,2,7,6,1,5 and target 8,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
My question is how to efficiently remove the duplication?
The following is my code:
public class Solution {
public static void main(String[] args) {
int[] input = { 10, 1, 2, 7, 6, 1, 5 };
// int[] input = { 2, 1, 1, 4, 4, 2 };
System.out.println(combinationSum2(input, 8));
}
private static class Entry {
List<Integer> list;
int target;
int index; // the previous index
public Entry(int target) {
list = new LinkedList<Integer>();
this.target = target;
}
public int add(int num, int index) {
this.list.add(num);
this.index = index;
this.target -= num;
return target;
}
public Entry copy() {
Entry copy = new Entry(this.target);
copy.list = new ArrayList<>();
copy.list.addAll(list);
copy.target = target;
copy.index = index;
return copy;
}
}
public static List<List<Integer>> combinationSum2(int[] input, int target) {
List<List<Integer>> ret = new LinkedList<List<Integer>>();
if (null == input || input.length <= 0)
return ret;
Arrays.sort(input);
int N = input.length;
Queue<Entry> pool = new LinkedList<Entry>();
for (int i = 0; i < N; i++) {
if (input[i] <= target) {
Entry entry = new Entry(target);
entry.add(input[i], i);
pool.add(entry);
}
}
while (!pool.isEmpty()) {
Entry cur = pool.poll();
if (cur.target == 0) {
ret.add(cur.list);
} else if (cur.target > 0) {
for (int i = cur.index + 1; i < N; i++) {
if (cur.target - input[i] >= 0) {
Entry copy = cur.copy();
copy.add(input[i], i);
pool.offer(copy);
} else {
break;
}
}
}
}
return ret;
}
}
My first idea is to sort the lists in the return list, them compare one by one to remove duplication. But is there any faster way? or any suggestion?
My suggestion is to use HashSet to prevent adding any existing entry.
The first thing to do is override the equals and hashCode function for your Entry class. (more material)
private static class Entry {
List<Integer> list;
int target;
int index;
int hash; // <---- add this
public Entry(int target) {
list = new LinkedList<Integer>();
this.target = target;
hash = target;
}
public int add(int num, int index) {
this.list.add(num);
this.index = index;
this.target -= num;
hash = hash * 17 + num;
return target;
}
public Entry copy() {
Entry copy = new Entry(this.target);
copy.list = new ArrayList<>();
copy.list.addAll(list);
copy.target = target;
copy.index = index;
copy.hash = hash;
return copy;
}
#Override
public boolean equals(Object obj) {
Entry e = (Entry) obj;
if ((this.target != e.target) || (this.list.size() != e.list.size())) {
return false;
}
for (int i = 0; i < this.list.size(); i++) {
if (!this.list.get(i).equals(e.list.get(i)))
return false;
}
return true;
}
#Override
public int hashCode() {
return hash;
}
}
The next step is to use a hashset to filter the result.
Set<Entry> nodup = new HashSet<Entry>();
while (!pool.isEmpty()) {
Entry cur = pool.poll();
if (cur.target == 0) {
nodup.add(cur);
} else if (cur.target > 0) {
// ... your code
}
}
for (Entry entry : nodup) {
ret.add(entry.list);
}
You can remove duplicates or repeated elements from List in Java by converting List into HashSet in Java. but before doing that just keep in mind that Set doesn't preserver insertion order which is guaranteed by List, in fact that’s the main difference between List and Set in Java.
So when you convert List to HashSet all duplicates elements will be removed but insertion order will be lost.
More detailed explanation can be found here
You can use hashing as another solution, though it will use O(n) in terms of space (the same in time).
Essentially, traverse the list from head to end. For every newly encountered element, we check whether it is in the hash set (HashSet): if yes, we remove it; otherwise we put it in.

Is Iterative Deepening Search supposed to be that slow?

My Data Structure:
class Cell
{
public:
struct CellLink
{
Cell *cell;
int weight;
};
public:
int row;
int column;
vector<CellLink> neighbors;
State state;
int totalCost = 0;
};
The primary function:
void AI::IterativeDeepeningSearch(Cell* cell)
{
Cell* temp;
int bound = 0;
while (true)
{
naturalFailure = false;
temp = IDShelper(cell, bound);
if (IsExit(temp))
{
break;
}
bound++;
}
}
The Helper:
Cell* AI::IDShelper(Cell* cell, int bound)
{
Cell* temp = cell;
SetEnvironment(cell, State::visited);
PrintEnvironment();
if (bound > 0)
{
for (int i = 0; i < cell->neighbors.size(); i++)
{
temp = IDShelper(cell->neighbors[i].cell, bound - 1);
if (IsExit(temp))
{
naturalFailure = true;
return temp;
}
}
}
else if (IsExit(cell))
{
return cell;
}
return temp;
}
I have made an Iterative Deepening Search for a maze. The problem is that it is taking literally hours to complete the search on a 21x21 maze while other algorithms take a couple of seconds.
I know that IDS is supposed to be slow but is it supposed to be that slow?
I think I can see why this is slow.
In your helper, you're visiting the neighbors like so:
if (bound > 0)
{
for (int i = 0; i < cell->neighbors.size(); i++)
{
temp = IDShelper(cell->neighbors[i].cell, bound - 1);
if (IsExit(temp))
{
naturalFailure = true;
return temp;
}
}
}
but you're never using past results. You mark something as visited, but never check whether it is already visited.