Tuesday, February 20, 2018

generate permutations of letters in a string

how to generate all permutations of the letters in a string? one method i like, for its intuitiveness - go to the last letter of the string and then recursively create strings by inserting previous letters in all possible positions. at each step a new list of strings will be created, with growing lengths

#include 
#include 
#include 

std::vector permute(std::string s, size_t index) {
    //std::cout << s << " " << index << std::endl;
    std::vector perms;
    if (index >= s.length()) {
        perms.push_back("");
        return perms;
    }
    
    std::string key = s.substr(index, 1);
    std::vector prev = permute(s, index + 1);
    for (size_t i = 0; i < prev.size(); ++i) {
        std::string p = prev[i];
        for (size_t j = 0; j <= p.length(); ++j) {
            std::string n = p.insert(j, key);
            perms.push_back(n);
            p = prev[i];
        }
    }
    return perms;
}

int main()
{
  std::string name = "12345";
  std::vector perms = permute(name, 0);
  for (auto& p : perms) {
    std::cout << p << std::endl;
  }
}

12345
21345
23145
23415
23451
13245
....


Saturday, February 17, 2018

Removing Characters from a String

found an interesting learning resource http://www.bogotobogo.com/ it also has a section on programming questions, not so extensive as the awesome http://geeksforgeeks.org/, but has some good problems to solve, with solutions. here is my solution to the "Removing Characters from a String" problem (http://www.bogotobogo.com/cplusplus/quiz_strings_arrays.php). it is not better, just a different approach
#include 
#include 

int main()
{
  std::string name("Ludwig Van Beethoven");
  std::string remove("aeiouAEIOU");
  int walk = 0;
  int last = 1;
  while (last < name.length() && walk < name.length()) {
      auto found = remove.find(name[walk], 0);
      if (found != std::string::npos) {
          char ch = name[walk];
          name[walk] = name[last];
          name[last] = ch;
          ++last;
      } else {
          ++walk;
      }
  }
  std::cout << "Hello, " << name.substr(0, walk+1) << "!\n";
}


Saturday, January 06, 2018

remove duplicates from an unsorted linked list

more fun with algorithms: how to remove duplicates from an unsorted linked list in cpp?
easy - just walk along the list and delete duplicate items.
but how to know an item is a duplicate?
well, for every item we could scan the list from the beginning, but this is a ridiculously naive solution - how about keeping all values we encounter while iterating and checking if we have already met a current value?
putting those in an unordered set would be good enough i'd say
#include 
#include 
using namespace std;

struct List {
 int data = 0;
 List* next = nullptr;
 List(int x) : data(x) {}
};

void remove_duplicates(List* head) {
 std::unordered_set cache;
 cache.insert(head->data);
 List* next = head->next;
 while (next != nullptr) {
  if (cache.count(next->data) > 0) {
   head->next = next->next;
   delete next;
   next = head->next;
  } else {
   cache.insert(next->data);
   head = next;
   next = head->next;
  }
 }
}

int main() {
 List* head = new List(1);
 List* list = head;
 for (int index = 2; index < 10; ++index) {
  List* next = new List(index);
  //a silly way to make duplicates in the list
  if (next->data % 2 == 0) {
   next->data = 2;
  } else if (next->data % 3 == 0) {
   next->data = 3;
  }
  list->next = next;
  list = next;
 }
 
 remove_duplicates(head);
 
 while (head != nullptr) {
  printf("%d\n", head->data);
  head = head->next;
 }
 
 return 0;
}

https://ideone.com/K19v5o