Trying TRIE DS implementation - data-structures

So, I'tried implementing TRIE DS, and while the node in the tree gets the value of Words assigned after addWord ends, but when I traverse the tree, The value that prints is zero. What did I do wrong, unable to point out. Please can someone help.
#include<iostream>
#include<string>
using namespace std;
struct trie{
int words;
int prefixes;
trie* edges[26];
};
void addWord(trie* vertex, string word){
if(word.length() == 0){
vertex->words = vertex->words + 1;
}
else{
// cout<<word<<endl;
vertex->prefixes = vertex->prefixes + 1;
char k = word[0];
if(vertex->edges[k - 'a'] == NULL){
trie *n = (trie*)malloc(sizeof(trie));
n->words = 0;
n->prefixes = 0;
for(int i=0;i<26;i++)
vertex->edges[i] = NULL;
vertex->edges[k - 'a'] = n;
}
word.erase(0, 1);
addWord(vertex->edges[k - 'a'], word);
}
};
void traverse(trie *vertex){
if(vertex != NULL){
for(int i=0;i<26;i++){
if(vertex->edges[i] != NULL){
traverse(vertex->edges[i]);
cout<<char(i+'a')<<" - "<<vertex->prefixes<< " : "<<vertex->words<<endl;
}
}
}
};
int main(){
string word = "hello";
trie* head = (trie*)malloc(sizeof(trie));
for(int i=0;i<26;i++)
head->edges[i] = NULL;
head->words = 0;
head->prefixes = 0;
addWord(head, word);
string s = "lo";
traverse(head);
return 0;
}

There are two issues with code:
In your addWord function, inside else block, in the for loop, change vertex->edges[i] = NULL; to n->edges[i] = NULL;
The problem you asked for is in your traverse function. You are not printing the words count for node pointed by say last o, you are printing it for the node that have o as it's edge. So just change this:
cout<<char(i+'a')<<" - "<<vertex->prefixes<< " : "<<vertex->words<<endl;
to this:
cout<<char(i+'a')<<" - "<<vertex->edges[i]->prefixes<< " : "<<vertex->edges[i]->words<<endl;

Related

A Scapegoat Tree That Just Won't Balance

So, I'm working on this project for Comp 272, Data Structures and Algorithms, and before anyone asks I have no one to help me. It's an online program through Athabasca University and for some unknown reason they didn't supply me with a tutor for this course, which is a first... So... Yeah. The question is as follows:
"(20 marks) Exercise 8.2. Illustrate what happens when the sequence 1, 5, 2, 4, 3 is added to an empty ScapegoatTree, and show where the credits described in the proof of Lemma 8.3 go, and how they are used during this sequence of additions."
This is my code, its complete and it compiles:
/*
Name: Westcott.
Assignment: 2, Question 3.
Date: 08-26-2022.
"(20 marks) Exercise 8.2. Illustrate what happens when the sequence 1, 5, 2, 4, 3 is added to an empty
ScapegoatTree, and show where the credits described in the proof of Lemma 8.3 go, and how they are used
during this sequence of additions."
*/
#include <iostream>
using namespace std;
class Node { // Originally I did this with Node as a subclass of sgTree but I found that this
public: // way was easier. This is actually my second attempt, from scratch, at doing this
int data; // problem. First version developed so many bugs I couldn't keep up with them.
Node* left;
Node* right;
Node* parent;
Node() : data(0), parent(NULL), left(NULL), right(NULL) {};
Node(int x) : data(x), parent(NULL), left(NULL), right(NULL) {};
~Node() {}; // Normally I would do a little more work on clean up but... Yea this problem didn't leave me much room.
Node* binarySearch(Node* root, int x); // The Node class only holds binarySearch in addition to its
// constructors/destructor, and of course the Node*'s left, right and parent.
};
class sgTree { // The sgTree keeps track of the root, n (the number of nodes in the tree), and q which is
public: // as Pat put it a 'high water mark'.
Node* root;
int n;
int q;
sgTree() : root(new Node()), n(1), q(1) {}
sgTree(int x) : root(new Node(x)), n(0), q(0) {}
~sgTree() {
delete root;
}
bool add(int x); // The add function is compounded, within it are findDepth and rebuild.
bool removeX(int x); // removeX works, but it didn't have a big part to play in this question,
int findDepth(Node* addedNode); // but I'll include it to maintain our sorted set interface.
void printTree(Node* u, int space) { // This was extra function I wrote to help me problem solve.
cout << "BINARY TREE DISPLAY" << endl; // this version only prints a title and then it calls printTreeSub on line 46.
cout << "________________________________________________\n\n" << endl;
printTreeSub(u, space);
cout << "________________________________________________\n\n" << endl;
}
int printTreeSub(Node* u, int space); // Function definition for this is on line 81.
int storeInArray(Node* ptr, Node* arr[], int i);// this is our function for storing all the elements of a tree in an array.
int size(Node* u); // this is size, defined on line 74.
void rebuild(Node* u); // And rebuild and buildBalanced are the stars of the show, defined on lines 262 and 282
Node* buildBalanced(Node** a, int i, int ns); // just above the main() funciton.
};
int log32(int q) { // As you can see there's two versions of this function.
int c = 0; // this is supposed to return the log of n to base 3/2.
while (q != 0) { // The version below I got from this website:
q = q / 2; // https://www.geeksforgeeks.org/scapegoat-tree-set-1-introduction-insertion/
c++; // It works fine but I prefer the one I wrote.
} // this is a much simpler function. It just divides q until its zero
return c; // and increments c on each division. Its not exact but it is based on what Pat said
} // in this lecture: https://www.youtube.com/watch?v=OGNUoDPVRCc&t=4852s
/*
static int const log32(int n)
{
double const log23 = 2.4663034623764317;
return (int)ceil(log23 * log(n));
}
*/
int sgTree::size(Node* u) {
if (u == NULL) {
return 0;
}
return 1 + size(u->left) + size(u->right); // Recursion in size();
}
int sgTree::printTreeSub(Node* u, int space) { // Here is my strange print function
if (u == NULL) return space; // I say strange because I'm not even 100% sure
space--; // how I got it to work. The order itself I worked out, but I built it
space -= printTreeSub(u->left, space); // and, originally, got a half decent tree, but then I just kept playing
if (u->right == NULL && u->left == NULL) { // around with increments, decrements, and returned values
cout << "\n\n\n" << u->data << "\n\n\n" << endl; // of space until it just sort of came together.
return 1; // Basically it prints the left most Node first and then prints every node
} // beneath that using recursion. I realized that by setting the for loop
for (int i = space; i >= 0; i--) { // on line 89 I could imitate different nodes having different heights in
cout << " "; // the tree. I figured that using n as an input I could take advantage of
} // the recursion to get an accurate tree. That much I understand.
cout << " " << u->data << "'s children are: "; // But it didn't work out quite how I wanted it to so I just kept playing
if (u->left != NULL) { // with space increments and decrements on different sides of the tree until
cout << u->left->data; // I got something pretty good.
}
else {
cout << "NULL";
}
if (u->right != NULL) {
cout << " and " << u->right->data;
}
else {
cout << " NULL";
}
cout << "\n\n" << endl;
space--;
space -= printTreeSub(u->right, space);
return 1;
}
int sgTree::storeInArray(Node* ptr, Node* a[], int i) { // This function took me a while to figure out.
if (ptr == NULL) { // The recursive insertions of values using i, when
return i; // i is defined by the very same recursion, makes this
} // a bit of a challenge to get your head around.
i = storeInArray(ptr->left, a, i); // Basically its just taking advantage on an inOrder
a[i] = ptr; // transversal to get the values stored into the array
i++; // in order from least to greatest.
return storeInArray(ptr->right, a, i);
}
Node* Node::binarySearch(Node* root, int x) { // I covered this in another question.
if (root->data == x) {
return root;
}
else if (x < root->data) {
if (root->left == NULL) {
return root;
}
return binarySearch(root->left, x);
}
else if (x > root->data) {
if (root->right == NULL) {
return root;
}
return binarySearch(root->right, x);
}
}
bool sgTree::add(int x) { // The add function itself isn't too difficult.
Node* addedNode = new Node(x); // We make a Node using our data, then we search for that Node
Node* parent = root->binarySearch(root, x); // in the tree. I amended binarySearch to return the parent
addedNode->parent = parent; // if it hits a NULL child, on lines 127 and 133.
if (x < parent->data) { // That way the new Node can just go into the returned parents child
parent->left = addedNode; // here is where we choose whether it enters the left or the right.
}
else if (x > parent->data) {
parent->right = addedNode;
}
int h = findDepth(addedNode); // We run findDepth() on the addedNode. I realize that this probably should
// have been a part of the binarySearch, it means we go down
if (h > log32(q)) { // the tree twice instead of once. I did look at changing binarySearch into searchAndDepth
// having binarySearch return an int for the height isn't a problem, but then that would
// mess up removeX and, I don't know. What's more important?
Node* w = addedNode->parent; // If this were going to be a database hosting millions of pieces of data I would give
while (3 * size(w) < 2 * size(w->parent)) { // that alot more consideration but, this is just an exercise after all so...
w = w->parent; // From there, we compare our height to the value output by log32(q) on line 152.
}
rebuild(w); // This expression 3 * size(w) < 2 * size(w->parent) is the formula on page 178 rewritten
//rebuild(root); // as a cross multiplication, clever. It keeps going up the tree until we find the scapegoat w.
// This is a much nicer result.
//See line 311.
} // Now, this is where my problems began. Pat says that this line should read: rebuild(w->parent);
n++; // but when I do that I get an error when w is the root. Because then w->parent is NULL. And in that case
q++; // line 258 throws an error because we're trying to set p equal to NULL's parent. It's not there.
return true; // So my work around was to just offset this by one and send rebuild(w). But that doesn't seem
} // to balance the tree just right. In fact, the best tree results when we replace w with root.
// and just rebalance the whole tree. But in any case, we increment n and q and lets pick this up on line 256.
int sgTree::findDepth(Node* addedNode) {
int d = 0;
while (addedNode != root) {
addedNode = addedNode->parent;
d++;
}
return d;
}
bool sgTree::removeX(int x) {
Node* u = root->binarySearch(root, x);
if (u->left == NULL && u->right == NULL) {
if (u == u->parent->left) {
u->parent->left = NULL;
}
if (u == u->parent->right) {
u->parent->right = NULL;
}
cout << u->data << " deleted" << endl;
n--;
delete u;
return true;
}
if (u->left != NULL && u->right == NULL) {
if (u->parent->left = u) {
u->parent->left = u->left;
}
else if (u->parent->right = u) {
u->parent->right = u->left;
}
cout << u->data << " deleted" << endl;
n--;
delete u;
return true;
}
if (u->left == NULL && u->right != NULL) {
if (u == u->parent->left) {
u->parent->left = u->right;
u->right->parent = u->parent;
}
else if (u == u->parent->right) {
u->parent->right = u->right;
u->right->parent = u->parent;
}
cout << u->data << " deleted" << endl;
n--;
delete u;
return true;
}
if (u->left != NULL && u->right != NULL) {
Node* X = u->right;
if (X->left == NULL) {
X->left = u->left;
if (u->parent != NULL) {
if (u->parent->right == u) {
u->parent->right == X;
}
else if (u->parent->left == u) {
u->parent->left = X;
}
}
else {
root = X;
}
X->parent = u->parent;
cout << u->data << " deleted" << endl;
n--;
delete u;
return true;
}
while (X->left != NULL) {
X = X->left;
}
X->parent->left = NULL;
X->left = u->left;
X->right = u->right;
if (u->parent != NULL) {
X->parent = u->parent;
}
cout << u->data << " deleted" << endl;
n--;
root = X;
delete u;
return true;
}
}
void sgTree::rebuild(Node* u) {
int ns = size(u); // Everything is pretty kosher here. Just get the number of nodes in the subtree.
Node* p = u->parent; // Originally I had n here instead of ns and... I don't want to talk about how long it took me to find that mistake...
/* It's funny because while writing the comments for this I'm like "Oh, hang on, if I just push the definition of p behind the if statement on line 262
and evaluate for whether or not u is NULL instead of p, that should solve all my problems! Yea, no, it doesn't. Because then for some reason it tries rebalancing
empty tree and... Yea I just have to stop myself from trying to fix this because everytime I do I get caught in an infinite loop of me chasing my tail in errors.
I think a solution could be found in buildBalanced, and I literally went through that function line by line, trying to comprehend a work around. I've included at
a photograph of that white board. Yea this is the code that Pat gave us... and its garbage. It doesn't work. Maybe its a C++ thing, I don't know... But I'm
getting frustrated again so I'm going to stop thinking about this part RIGHT HERE, and move on LOL*/
Node** a = new Node * [ns]; // a Node pointer-pointer array... again, another fine piece of code from the textbook. Sorry, trying to stay positive here.
storeInArray(u, a, 0); // See Line 112
if (p == NULL) { // Okay, once we have our array we use buildBalanced to rebuild the subtree with respect to which
root = buildBalanced(a, 0, ns); // child u is relative to its parent.
root->parent = NULL; // See line 281 for buildBalanced().
}
else if (p->right == u) {
p->right = buildBalanced(a, 0, ns);
p->right->parent = p;
}
else {
p->left = buildBalanced(a, 0, ns);
p->left->parent = p;
}
}
Node* sgTree::buildBalanced(Node** a, int i, int ns) { // This is without a doubt one of the hardest functions I've ever had
if (ns == 0) { // the displeasure of trying to understand... Trying to stay positive.
return NULL; // I've gone through it, in a line by line implementation of the array:
} // a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} you can find that analysis in
int m = ns / 2; // the photo buildBalanced_Analysis.
a[i + m]->left = buildBalanced(a, i, m); // As confusing as it is, I have to admit that it is a beautiful function.
if (a[i + m]->left != NULL) { // It basically uses the two integers i and m to simultaneously
a[i + m]->left->parent = a[i + m]; // regulate the organization of the new tree and to specifically
} // grab the right value from the array when its needed.
a[i + m]->right = buildBalanced(a, i + m + 1, ns - m - 1); // but trying to map this out didn't help me to solve the issues I've been having.
if (a[i + m]->right != NULL) {
a[i + m]->right->parent = a[i + m];
}
return a[i + m];
}
int main() {
sgTree newTree(1);
int a[] = { 5, 2, 4, 3 };
for (int i = 0; i < (sizeof(a) / sizeof(a[0])); i++) {
newTree.add(a[i]);
}
newTree.printTree(newTree.root, newTree.n);
/*
This is a nice test, when paired with rebuild(root), that too me is the only thing that approaches redeeming this whole question.
sgTree newTreeB(1);
int b[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < (sizeof(b) / sizeof(b[0])); i++) {
newTreeB.add(b[i]);
}
newTreeB.printTree(newTreeB.root, newTreeB.n);
*/
}
Now the issue itself is not that hard to understand. My tree should look like this:
But instead, it looks like this, with 5 at the root and the values 1 and 4 as the leaves:
I'm confident that the problem lives somewhere around line 159 and in those first few calls to buildBalanced. The comments in the code itself elaborate more on the issue. I've spent days just pouring over this trying everything I can think of to make it work and... Yeah... I just can't figure it out.

I got a Data Structure task and i was stuck in String Sorting function anyone help me out?

The idea of the project is to maintain the data of the dictionary in such a way that searching the word
becomes easy and efficient. Dictionary Dataset will be maintained in a text file. User will load the file
and create a linked list in such a way that all words with arranged in a sorted order just like a dictionary.
Nodes A,B,C to Z will be created while reading the file according to words. Suppose if there is no word
with letter F then node F will not be created
Here is and example Click here
My approach:
read all words from text file
sort all words in alphabetical order
create list
I have defined the maximum length of a word as 5, of course you have to adapt this to your needs. It depends on how the words are stored in the text file, for example if each line contains one word the length of the array is logically the number of lines in the text file.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define size_of_array 8
typedef struct word{
char w[5];
struct word* next;
} word;
typedef struct node{
char c;//contains the character with which the words begin
struct node* next;
struct word* firstWord;
} node;
node *anchor = NULL; //points to first node of the list
node *getNodeByChar(char c){
node *ptr = anchor;
while(ptr != NULL && ptr->c != c){
ptr = ptr->next;
}
return ptr;
}
void addWordToNode(char c, char *w){
word *newWord = (word *)malloc(sizeof(word));
strcpy(newWord->w,w);
newWord->next = NULL;
node *n = getNodeByChar(c);
word *wrd = n->firstWord;
if(wrd == NULL){ //if newWord is the first word of the node
//set firstword to newWord
n->firstWord = newWord;
}else{
//append newWord to wordlist of node
while(wrd->next != NULL){
wrd = wrd->next;
}
wrd->next = newWord;
}
}
void addNode(char c){
node *newNode = (node *)malloc(sizeof(node));
newNode->c = c;
newNode->next = NULL;
newNode->firstWord = NULL;
if(anchor == NULL){
//newNode is first Node set anchor to newNode
anchor = newNode;
}else{
//append node to list
node *ptr = anchor;
while(ptr->next != NULL){
ptr = ptr->next;
}
ptr->next = newNode;
}
}
void createList(char array[][5]){
char currentStartChar;
currentStartChar = array[0][0];
addNode(currentStartChar);//add first node
for(int i = 0; i < size_of_array; i++){
if(array[i][0] != currentStartChar){//if beginning char changes add new Node
currentStartChar = array[i][0];
addNode(currentStartChar);
}
addWordToNode(currentStartChar,array[i]);//add word to Node
}
}
void printList(){ //printing the list
node *ptr = anchor;
word *wPtr = NULL;
while(ptr != NULL){//iterate through al nodes
printf("%c: ",ptr->c);
if(ptr->firstWord != NULL){
wPtr = ptr->firstWord;
while(wPtr != NULL){ //iterate through all words of node 'ptr'
//with char 'ptr->c'
printf("%s, ",wPtr->w);
wPtr = wPtr->next;//next word
}
}
printf("\n");
ptr = ptr->next;//next node
}
}
//function to display array
void display(char array[][5]){
for(int i=0; i<size_of_array; i++){
printf("%s ", array[i]);
}
printf("\n");
}
int main()
{
//Words out of text file
char array[size_of_array][5] = {
"Ape",
"Boy",
"Ant",
"Too",
"Dog",
"Dad",
"Abc",
"TTL"
};
//display the original array
printf("Original array: ");
display(array);
char temp[5];
//Sort array using the Bubble Sort algorithm
for(int i=0; i<size_of_array; i++){
for(int j=0; j<size_of_array-1-i; j++){
if(strcmp(array[j], array[j+1]) > 0){
//swap array[j] and array[j+1]
strcpy(temp, array[j]);
strcpy(array[j], array[j+1]);
strcpy(array[j+1], temp);
}
}
}
//display the sorted array
printf("Sorted Array: ");
display(array);
createList(array);
printf("\n\n");
printList();
return 0;
}
Output:
Original array: Ape Boy Ant Too Dog Dad Abc TTL
Sorted Array: Abc Ant Ape Boy Dad Dog TTL Too
A: Abc, Ant, Ape,
B: Boy,
D: Dad, Dog,
T: TTL, Too,

Recursive algorithm to find all possible solutions in a nonogram row

I am trying to write a simple nonogram solver, in a kind of bruteforce way, but I am stuck on a relatively easy task. Let's say I have a row with clues [2,3] that has a length of 10
so the solutions are:
$$-$$$----
$$--$$$---
$$---$$$--
$$----$$$-
$$-----$$$
-$$----$$$
--$$---$$$
---$$--$$$
----$$-$$$
-$$---$$$-
--$$-$$$--
I want to find all the possible solutions for a row
I know that I have to consider each block separately, and each block will have an availible space of n-(sum of remaining blocks length + number of remaining blocks) but I do not know how to progress from here
Well, this question already have a good answer, so think of this one more as an advertisement of python's prowess.
def place(blocks,total):
if not blocks: return ["-"*total]
if blocks[0]>total: return []
starts = total-blocks[0] #starts = 2 means possible starting indexes are [0,1,2]
if len(blocks)==1: #this is special case
return [("-"*i+"$"*blocks[0]+"-"*(starts-i)) for i in range(starts+1)]
ans = []
for i in range(total-blocks[0]): #append current solutions
for sol in place(blocks[1:],starts-i-1): #with all possible other solutiona
ans.append("-"*i+"$"*blocks[0]+"-"+sol)
return ans
To test it:
for i in place([2,3,2],12):
print(i)
Which produces output like:
$$-$$$-$$---
$$-$$$--$$--
$$-$$$---$$-
$$-$$$----$$
$$--$$$-$$--
$$--$$$--$$-
$$--$$$---$$
$$---$$$-$$-
$$---$$$--$$
$$----$$$-$$
-$$-$$$-$$--
-$$-$$$--$$-
-$$-$$$---$$
-$$--$$$-$$-
-$$--$$$--$$
-$$---$$$-$$
--$$-$$$-$$-
--$$-$$$--$$
--$$--$$$-$$
---$$-$$$-$$
This is what i got:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef std::vector<bool> tRow;
void printRow(tRow row){
for (bool i : row){
std::cout << ((i) ? '$' : '-');
}
std::cout << std::endl;
}
int requiredCells(const std::vector<int> nums){
int sum = 0;
for (int i : nums){
sum += (i + 1); // The number + the at-least-one-cell gap at is right
}
return (sum == 0) ? 0 : sum - 1; // The right-most number don't need any gap
}
bool appendRow(tRow init, const std::vector<int> pendingNums, unsigned int rowSize, std::vector<tRow> &comb){
if (pendingNums.size() <= 0){
comb.push_back(init);
return false;
}
int cellsRequired = requiredCells(pendingNums);
if (cellsRequired > rowSize){
return false; // There are no combinations
}
tRow prefix;
int gapSize = 0;
std::vector<int> pNumsAux = pendingNums;
pNumsAux.erase(pNumsAux.begin());
unsigned int space = rowSize;
while ((gapSize + cellsRequired) <= rowSize){
space = rowSize;
space -= gapSize;
prefix.clear();
prefix = init;
for (int i = 0; i < gapSize; ++i){
prefix.push_back(false);
}
for (int i = 0; i < pendingNums[0]; ++i){
prefix.push_back(true);
space--;
}
if (space > 0){
prefix.push_back(false);
space--;
}
appendRow(prefix, pNumsAux, space, comb);
++gapSize;
}
return true;
}
std::vector<tRow> getCombinations(const std::vector<int> row, unsigned int rowSize) {
std::vector<tRow> comb;
tRow init;
appendRow(init, row, rowSize, comb);
return comb;
}
int main(){
std::vector<int> row = { 2, 3 };
auto ret = getCombinations(row, 10);
for (tRow r : ret){
while (r.size() < 10)
r.push_back(false);
printRow(r);
}
return 0;
}
And my output is:
$$-$$$----
$$--$$$---
$$---$$$--
$$----$$$--
$$-----$$$
-$$-$$$----
-$$--$$$--
-$$---$$$-
-$$----$$$-
--$$-$$$--
--$$--$$$-
--$$---$$$
---$$-$$$-
---$$--$$$
----$$-$$$
For sure, this must be absolutely improvable.
Note: i did't test it more than already written case
Hope it works for you

Given a string, find its first non-repeating character in only One scan

Given a string, find the first non-repeating character in it. For
example, if the input string is “GeeksforGeeks”, then output should be
‘f’.
We can use string characters as index and build a count array.
Following is the algorithm.
Scan the string from left to right and construct the count array or
HashMap.
Again, scan the string from left to right and check for
count of each character, if you find an element who's count is 1,
return it.
Above problem and algorithm is from GeeksForGeeks
But it requires two scan of an array. I want to find first non-repeating character in only one scan.
I implemented above algorithm Please check it also on Ideone:
import java.util.HashMap;
import java.util.Scanner;
/**
*
* #author Neelabh
*/
public class FirstNonRepeatedCharacter {
public static void main(String [] args){
Scanner scan=new Scanner(System.in);
String string=scan.next();
int len=string.length();
HashMap<Character, Integer> hashMap=new HashMap<Character, Integer>();
//First Scan
for(int i = 0; i <len;i++){
char currentCharacter=string.charAt(i);
if(!hashMap.containsKey(currentCharacter)){
hashMap.put(currentCharacter, 1);
}
else{
hashMap.put(currentCharacter, hashMap.get(currentCharacter)+1);
}
}
// Second Scan
boolean flag=false;
char firstNonRepeatingChar = 0;
for(int i=0;i<len;i++){
char c=string.charAt(i);
if(hashMap.get(c)==1){
flag=true;
firstNonRepeatingChar=c;
break;
}
}
if(flag==true)
System.out.println("firstNonRepeatingChar is "+firstNonRepeatingChar);
else
System.out.println("There is no such type of character");
}
}
GeeksforGeeks also suggest efficient method but I think it is also two scan. Following solution is from GeeksForGeeks
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#define NO_OF_CHARS 256
// Structure to store count of a character and index of the first
// occurrence in the input string
struct countIndex {
int count;
int index;
};
/* Returns an array of above structure type. The size of
array is NO_OF_CHARS */
struct countIndex *getCharCountArray(char *str)
{
struct countIndex *count =
(struct countIndex *)calloc(sizeof(countIndex), NO_OF_CHARS);
int i;
// This is First Scan
for (i = 0; *(str+i); i++)
{
(count[*(str+i)].count)++;
// If it's first occurrence, then store the index
if (count[*(str+i)].count == 1)
count[*(str+i)].index = i;
}
return count;
}
/* The function returns index of the first non-repeating
character in a string. If all characters are repeating
then reurns INT_MAX */
int firstNonRepeating(char *str)
{
struct countIndex *count = getCharCountArray(str);
int result = INT_MAX, i;
//Second Scan
for (i = 0; i < NO_OF_CHARS; i++)
{
// If this character occurs only once and appears
// before the current result, then update the result
if (count[i].count == 1 && result > count[i].index)
result = count[i].index;
}
free(count); // To avoid memory leak
return result;
}
/* Driver program to test above function */
int main()
{
char str[] = "geeksforgeeks";
int index = firstNonRepeating(str);
if (index == INT_MAX)
printf("Either all characters are repeating or string is empty");
else
printf("First non-repeating character is %c", str[index]);
getchar();
return 0;
}
You can store 2 arrays: count of each character and the first occurrence(and fill both of them during the first scan). Then the second scan will be unnecessary.
Use String functions of java then you find the solution in only one for loop
The Example is show below
import java.util.Scanner;
public class firstoccurance {
public static void main(String args[]){
char [] a ={'h','h','l','l','o'};
//Scanner sc=new Scanner(System.in);
String s=new String(a);//sc.next();
char c;
int i;
int length=s.length();
for(i=0;i<length;i++)
{
c=s.charAt(i);
if(s.indexOf(c)==s.lastIndexOf(c))
{
System.out.println("first non repeating char in a string "+c);
break;
}
else if(i==length-1)
{
System.out.println("no single char");
}
}
}
}
In following solution I declare one class CharCountAndPosition which stores firstIndex and frequencyOfchar. During the reading string characterwise, firstIndex stores the first encounter of character and frequencyOfchar stores the total occurrence of characters.
We will make array of CharCountAndPosition step:1 and Initialize it step2.
During scanning the string, Initialize the firstIndex and frequencyOfchar for every character step3.
Now In the step4 check the array of CharCountAndPosition, find the character with frequency==1 and minimum firstIndex
Over all time complexity is O(n+256), where n is size of string. O(n+256) is equivalent to O(n) Because 256 is constant. Please find solution of this on ideone
public class FirstNonRepeatedCharacterEfficient {
public static void main(String [] args){
// step1: make array of CharCountAndPosition.
CharCountAndPosition [] array=new CharCountAndPosition[256];
// step2: Initialize array with object of CharCountAndPosition.
for(int i=0;i<256;i++)
{
array[i]=new CharCountAndPosition();
}
Scanner scan=new Scanner(System.in);
String str=scan.next();
int len=str.length();
// step 3
for(int i=0;i<len;i++){
char c=str.charAt(i);
int index=c-'a';
int frequency=array[index].frequencyOfchar;
if(frequency==0)
array[index].firstIndex=i;
array[index].frequencyOfchar=frequency+1;
//System.out.println(c+" "+array[index].frequencyOfchar);
}
boolean flag=false;
int firstPosition=Integer.MAX_VALUE;
for(int i=0;i<256;i++){
// Step4
if(array[i].frequencyOfchar==1){
//System.out.println("character="+(char)(i+(int)'a'));
if(firstPosition> array[i].firstIndex){
firstPosition=array[i].firstIndex;
flag=true;
}
}
}
if(flag==true)
System.out.println(str.charAt(firstPosition));
else
System.out.println("There is no such type of character");
}
}
class CharCountAndPosition{
int firstIndex;
int frequencyOfchar;
}
A solution in javascript with a lookup table:
var sample="It requires two scan of an array I want to find first non repeating character in only one scan";
var sampleArray=sample.split("");
var table=Object.create(null);
sampleArray.forEach(function(char,idx){
char=char.toLowerCase();
var pos=table[char];
if(typeof(pos)=="number"){
table[char]=sampleArray.length; //a duplicate found; we'll assign some invalid index value to this entry and discard these characters later
return;
}
table[char]=idx; //index of first occurance of this character
});
var uniques=Object.keys(table).filter(function(k){
return table[k]<sampleArray.length;
}).map(function(k){
return {key:k,pos:table[k]};
});
uniques.sort(function(a,b){
return a.pos-b.pos;
});
uniques.toSource(); //[{key:"q", pos:5}, {key:"u", pos:6}, {key:"d", pos:46}, {key:"p", pos:60}, {key:"g", pos:66}, {key:"h", pos:69}, {key:"l", pos:83}]
(uniques.shift()||{}).key; //q
Following C prog, add char specific value to 'count' if char didn't occurred before, removes char specific value from 'count' if char had occurred before. At the end I get a 'count' that has char specific value which indicate what was that char!
//TO DO:
//If multiple unique char occurs, which one is occurred before?
//Is is possible to get required values (1,2,4,8,..) till _Z_ and _z_?
#include <stdio.h>
#define _A_ 1
#define _B_ 2
#define _C_ 4
#define _D_ 8
//And so on till _Z
//Same for '_a' to '_z'
#define ADDIFNONREP(C) if(count & C) count = count & ~C; else count = count | C; break;
char getNonRepChar(char *str)
{
int i = 0, count = 0;
for(i = 0; str[i] != '\0'; i++)
{
switch(str[i])
{
case 'A':
ADDIFNONREP(_A_);
case 'B':
ADDIFNONREP(_B_);
case 'C':
ADDIFNONREP(_C_);
case 'D':
ADDIFNONREP(_D_);
//And so on
//Same for 'a' to 'z'
}
}
switch(count)
{
case _A_:
return 'A';
case _B_:
return 'B';
case _C_:
return 'C';
case _D_:
return 'D';
//And so on
//Same for 'a' to 'z'
}
}
int main()
{
char str[] = "ABCDABC";
char c = getNonRepChar(str);
printf("%c\n", c); //Prints D
return 0;
}
You can maintain a queue of keys as they are added to the hash map (you add your key to the queue if you add a new key to the hash map). After string scan, you use the queue to obtain the order of the keys as they were added to the map. This functionality is exactly what Java standard library class OrderedHashMap does.
Here is my take on the problem.
Iterate through string. Check if hashset contains the character. If so delete it from array. If not present just add it to the array and hashset.
NSMutableSet *repeated = [[NSMutableSet alloc] init]; //Hashset
NSMutableArray *nonRepeated = [[NSMutableArray alloc] init]; //Array
for (int i=0; i<[test length]; i++) {
NSString *currentObj = [NSString stringWithFormat:#"%c", [test characterAtIndex:i]]; //No support for primitive data types.
if ([repeated containsObject:currentObj]) {
[nonRepeated removeObject:currentObj];// in obj-c nothing happens even if nonrepeted in nil
continue;
}
[repeated addObject:currentObj];
[nonRepeated addObject:currentObj];
}
NSLog(#"This is the character %#", [nonRepeated objectAtIndex:0]);
If you can restrict yourself to strings of ASCII characters, I would recommend a lookup table instead of a hash table. This lookup table would have only 128 entries.
A possible approach would be as follows.
We start with an empty queue Q (may be implemented using linked lists) and a lookup table T. For a character ch, T[ch] stores a pointer to a queue node containing the character ch and the index of the first occurrence of ch in the string. Initially, all entries of T are NULL.
Each queue node stores the character and the first occurrence index as specified earlier, and also has a special boolean flag named removed which indicates that the node has been removed from the queue.
Read the string character by character. If the ith character is ch, check if T[ch] = NULL. If so, this is the first occurrence of ch in the string. Then add a node for ch containing the index i to the queue.
If T[ch] is not NULL, this is a repeating character. If the node pointed to by T[ch] has already been removed (i.e. the removed flag of the node is set), then nothing needs to be done. Otherwise, remove the node from the queue by manipulating the pointers of the previous and next nodes. Also set the removed flag of the node to indicate that the node is now removed. Note that we do not free/delete the node at this stage, nor do we set T[ch] back to NULL.
If we proceed in this way, the nodes for all the repeating characters will be removed from the queue. The removed flag is used to ensure that no node is removed twice from the queue if the character occurs more than two times.
After the string has been completely processed, the first node of the linked list will contain the character code as well as the index of the first non-repeating character. Then, the memory can be freed by iterating over the entries of lookup table T and freeing any non-NULL entries.
Here is a C implementation. Here, instead of the removed flag, I set the prev and next pointers of the current node to NULL when it is removed, and check for that to see if a node has already been removed.
#include <stdio.h>
#include <stdlib.h>
struct queue_node {
int ch;
int index;
struct queue_node *prev;
struct queue_node *next;
};
void print_queue (struct queue_node *head);
int main (void)
{
int i;
struct queue_node *lookup_entry[128];
struct queue_node *head;
struct queue_node *last;
struct queue_node *cur_node, *prev_node, *next_node;
char str [] = "GeeksforGeeks";
head = malloc (sizeof (struct queue_node));
last = head;
last->prev = last->next = NULL;
for (i = 0; i < 128; i++) {
lookup_entry[i] = NULL;
}
for (i = 0; str[i] != '\0'; i++) {
cur_node = lookup_entry[str[i]];
if (cur_node != NULL) {
/* it is a repeating character */
if (cur_node->prev != NULL) {
/* Entry has not been removed. Remove it from the queue. */
prev_node = cur_node->prev;
next_node = cur_node->next;
prev_node->next = next_node;
if (next_node != NULL) {
next_node->prev = prev_node;
} else {
/* Last node was removed */
last = prev_node;
}
cur_node->prev = NULL;
cur_node->next = NULL;
/* We will not free the node now. Instead, free
* all nodes in a single pass afterwards.
*/
}
} else {
/* This is the first occurence - add an entry to the queue */
struct queue_node *newnode = malloc (sizeof(struct queue_node));
newnode->ch = str[i];
newnode->index = i;
newnode->prev = last;
newnode->next = NULL;
last->next = newnode;
last = newnode;
lookup_entry[str[i]] = newnode;
}
print_queue (head);
}
last = head->next;
while (last != NULL) {
printf ("Non-repeating char: %c at index %d.\n", last->ch, last->index);
last = last->next;
}
/* Free the queue memory */
for (i = 0; i < 128; i++) {
if (lookup_entry[i] != NULL) {
free (lookup_entry[i]);
lookup_entry[i] = NULL;
}
}
free (head);
return (0);
}
void print_queue (struct queue_node *head) {
struct queue_node *tmp = head->next;
printf ("Queue: ");
while (tmp != NULL) {
printf ("%c:%d ", tmp->ch, tmp->index);
tmp = tmp->next;
}
printf ("\n");
}
Instead of making things more and more complex, I can use three for loops to tackle this.
class test{
public static void main(String args[]){
String s="STRESST";//Your input can be given here.
char a[]=new char[s.length()];
for(int i=0;i<s.length();i++){
a[i]=s.charAt(i);
}
for(int i=0;i<s.length();i++){
int flag=0;
for(int j=0;j<s.length();j++){
if(a[i]==a[j]){
flag++;
}
}
if(flag==1){
System.out.println(a[i]+" is not repeated");
break;
}
}
}
}
I guess it will be helpful for people who are just gonna look at the logic part without any complex methods used in the program.
This can be done in one Scan using the substring method. Do it like this:
String str="your String";<br>
String s[]= str.split("");<br>
int n=str.length();<br>
int i=0;<br><br>
for(String ss:s){
if(!str.substring(i+1,n).contains(ss)){
System.out.println(ss);
}
}
This will have the lowest complexity and will search for it even without completing one full scan.
Add each character to a HashSet and check whether hashset.add() returns true, if it returns false ,then remove the character from hashset.
Then getting the first value of the hashset will give you the first non repeated character.
Algorithm:
for(i=0;i<str.length;i++)
{
HashSet hashSet=new HashSet<>()
if(!hashSet.add(str[i))
hashSet.remove(str[i])
}
hashset.get(0) will give the non repeated character.
i have this program which is more simple,
this is not using any data structures
public static char findFirstNonRepChar(String input){
char currentChar = '\0';
int len = input.length();
for(int i=0;i<len;i++){
currentChar = input.charAt(i);
if((i!=0) && (currentChar!=input.charAt(i-1)) && (i==input.lastIndexOf(currentChar))){
return currentChar;
}
}
return currentChar;
}
A simple (non hashed) version...
public static String firstNRC(String s) {
String c = "";
while(s.length() > 0) {
c = "" + s.charAt(0);
if(! s.substring(1).contains(c)) return c;
s = s.replace(c, "");
}
return "";
}
or
public static char firstNRC(String s) {
s += " ";
for(int i = 0; i < s.length() - 1; i++)
if( s.split("" + s.charAt(i)).length == 2 ) return s.charAt(i);
return ' ';
}
//This is the simple logic for finding first non-repeated character....
public static void main(String[] args) {
String s = "GeeksforGeeks";
for (int i = 0; i < s.length(); i++) {
char begin = s.charAt(i);
String begin1 = String.valueOf(begin);
String end = s.substring(0, i) + s.substring(i + 1);
if (end.contains(begin1));
else {
i = s.length() + 1;
System.out.println(begin1);
}
}
}
#Test
public void testNonRepeadLetter() {
assertEquals('f', firstNonRepeatLetter("GeeksforGeeks"));
assertEquals('I', firstNonRepeatLetter("teststestsI"));
assertEquals('1', firstNonRepeatLetter("123aloalo"));
assertEquals('o', firstNonRepeatLetter("o"));
}
private char firstNonRepeatLetter(String s) {
if (s == null || s.isEmpty()) {
throw new IllegalArgumentException(s);
}
Set<Character> set = new LinkedHashSet<>();
for (int i = 0; i < s.length(); i++) {
char charAt = s.charAt(i);
if (set.contains(charAt)) {
set.remove(charAt);
} else {
set.add(charAt);
}
}
return set.iterator().next();
}
here is a tested code in java. note that it is possible that no non repeated character is found, and for that we return a '0'
// find first non repeated character in a string
static char firstNR( String str){
int i, j, l;
char letter;
int[] k = new int[100];
j = str.length();
if ( j > 100) return '0';
for (i=0; i< j; i++){
k[i] = 0;
}
for (i=0; i<j; i++){
for (l=0; l<j; l++){
if (str.charAt(i) == str.charAt(l))
k[i]++;
}
}
for (i=0; i<j; i++){
if (k[i] == 1)
return str.charAt(i);
}
return '0';
Here is the logic to find the first non-repeatable letter in a String.
String name = "TestRepeat";
Set <Character> set = new LinkedHashSet<Character>();
List<Character> list = new ArrayList<Character>();
char[] ch = name.toCharArray();
for (char c :ch) {
set.add(c);
list.add(c);
}
Iterator<Character> itr1 = set.iterator();
Iterator<Character> itr2= list.iterator();
while(itr1.hasNext()){
int flag =0;
Character setNext= itr1.next();
for(int i=0; i<list.size(); i++){
Character listNext= list.get(i);
if(listNext.compareTo(setNext)== 0){
flag ++;
}
}
if(flag==1){
System.out.println("Character: "+setNext);
break;
}
}
it is very easy....you can do it without collection in java..
public class FirstNonRepeatedString{
public static void main(String args[]) {
String input ="GeeksforGeeks";
char process[] = input.toCharArray();
boolean status = false;
int index = 0;
for (int i = 0; i < process.length; i++) {
for (int j = 0; j < process.length; j++) {
if (i == j) {
continue;
} else {
if (process[i] == process[j]) {
status = false;
break;
} else {
status = true;
index = i;
}
}
}
if (status) {
System.out.println("First non-repeated string is : " + process[index]);
break;
}
}
}
}
We can create LinkedHashMap having each character from the string and it's respective count. And then traverse through the map when you come across char with count as 1 return that character. Below is the function for the same.
private static char findFirstNonRepeatedChar(String string) {
LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
for(int i=0;i< string.length();i++){
if(map.containsKey(string.charAt(i)))
map.put(string.charAt(i),map.get(string.charAt(i))+1);
else
map.put(string.charAt(i),1);
}
for(Entry<Character,Integer> entry : map.entrySet()){
if(entry.getValue() == 1){
return entry.getKey();
}
}
return ' ';
}
One Pass Solution.
I have used linked Hashmap here to maintain the insertion order. So I go through all the characters of a string and store it values in Linked HashMap. After that I traverse through the Linked Hash map and whichever first key will have its value equal to 1, I will print that key and exit the program.
import java.util.*;
class demo
{
public static void main(String args[])
{
String str="GeekGsQuizk";
HashMap <Character,Integer>hm=new LinkedHashMap<Character,Integer>();
for(int i=0;i<str.length();i++)
{
if(!hm.containsKey(str.charAt(i)))
hm.put(str.charAt(i),1);
else
hm.put(str.charAt(i),hm.get(str.charAt(i))+1);
}
for (Character key : hm.keySet())
{
if(hm.get(key)==1)
{
System.out.println(key);
System.exit(0) ;
}
}
}
}
I know this comes one year late, but I think if you use LinkedHashMap in your solution instead of using a HashMap, you will have the order guaranteed in the resulting map and you can directly return the key with the corresponding value as 1.
Not sure if this is what you wanted though as you will have to iterate over the map (not the string) after you are done populating it - but just my 2 cents.
Regards,
-Vini
Finding first non-repeated character in one pass O(n ) , without using indexOf and lastIndexOf methods
package nee.com;
public class FirstNonRepeatedCharacterinOnePass {
public static void printFirstNonRepeatedCharacter(String str){
String strToCaps=str.toUpperCase();
char ch[]=strToCaps.toCharArray();
StringBuilder sb=new StringBuilder();
// ASCII range for A-Z ( 91-65 =26)
boolean b[]=new boolean[26];
for(int i=0;i<ch.length;i++){
if(b[ch[i]-65]==false){
b[ch[i]-65]=true;
}
else{
//add repeated char to StringBuilder
sb.append(ch[i]+"");
}
}
for(int i=0;i<ch.length;i++){
// if char is not there in StringBuilder means it is non repeated
if(sb.indexOf(ch[i]+"")==-1){
System.out.println(" first non repeated in lower case ...."+Character.toLowerCase((ch[i])));
break;
}
}
}
public static void main(String g[]){
String str="abczdabddcn";
printFirstNonRepeatedCharacter(str);
}
}
I did the same using LinkedHashSet. Following is the code snippet:
System.out.print("Please enter the string :");
str=sc.nextLine();
if(null==str || str.equals("")) {
break;
}else {
chArr=str.toLowerCase().toCharArray();
set=new LinkedHashSet<Character>();
dupSet=new LinkedHashSet<Character>();
for(char chVal:chArr) {
if(set.contains(chVal)) {
dupSet.add(chVal);
}else {
set.add(chVal);
}
}
set.removeAll(dupSet);
System.out.println("First unique :"+set.toArray()[0]);
}
You can find this question here
For code of the below algorithm refer this link (My implementation with test cases)
Using linkedlist in combination with hashMap
I have a solution which solves it in O(n) time One array pass and O(1) space
Inreality -> O(1) space is O(26) space
Algorithm
1) every time you visit a character for the first time
Create a node for the linkedList(storing that character).Append it at the end of the lnkedList.Add an entry in the hashMap storing for recently appended charater the address of the node in the linked list that was before that character.If character is appended to an empty linked list store null for vale in hash map.
2) Now if you encounter the same charactter again
Remove that element from the linkedlist using the address stored in the hash map and now you have to update for the element that was after the deleted element ,the previous element for it. Make it equal to the previous element of the deleted element.
Complexity Analysis
LinkedlIst add element -> O(1)
LinkedlIst delete element -> O(1)
HashMap -> O(1)
space O(1)
pass -> one in O(n)
#include<bits/stdc++.h>
using namespace std;
typedef struct node
{
char ch;
node *next;
}node;
char firstNotRepeatingCharacter(string &s)
{
char ans = '_';
map<char,node*> mp;//hash map atmost may consume O(26) space
node *head = NULL;//linkedlist atmost may consume O(26) space
node *last;// to append at last in O(1)
node *temp1 = NULL;
node *temp2 = new node[1];
temp2->ch = '$';
temp2->next = NULL;
//This is my one pass of array//
for(int i = 0;i < s.size();++i)
{
//first occurence of character//
if(mp.find(s[i]) == mp.end())
{
node *temp = new node[1];
temp->ch = s[i];
temp->next = NULL;
if(head == NULL)
{
head = temp;
last = temp;
mp.insert(make_pair(s[i],temp1));
}
else
{
last->next = temp;
mp.insert(make_pair(s[i],last));
last = temp;
}
}
//Repeated occurence//
else
{
node *temp = mp[s[i]];
if(mp[s[i]] != temp2)
{
if(temp == temp1)
{
head = head->next;
if((head)!=NULL){mp[head->ch] = temp1;}
else last = head;
mp[s[i]] = temp2;
}
else if((temp->next) != NULL)
{
temp->next = temp->next->next;
if((temp->next) != NULL){mp[temp->next->ch] = temp;}
else last = temp;
mp[s[i]] = temp2;
}
else
{
;
}
}
}
if(head == NULL){;}
else {ans = head->ch;}
return ans;
}
int main()
{
int T;
cin >> T;
while(T--)
{
string str;
cin >> str;
cout << str << " -> " << firstNotRepeatingCharacter(str)<< endl;
}
return 0;
}
Requires one scan only.
Uses a deque (saves char) and a hashmap (saves char->node). On repeating char, get char's node in deque using hashmap and remove it from deque (in O(1) time) but keep the char in hashmap with null node value. peek() gives the 1st unique character.
[pseudocode]
char? findFirstUniqueChar(s):
if s == null:
throw
deque<char>() dq = new
hashmap<char, node<char>> chToNodeMap = new
for i = 0, i < s.length(), i++:
ch = s[i]
if !chToNodeMap.hasKey(ch):
chToNodeMap[ch] = dq.enqueue(ch)
else:
chNode = chToNodeMap[ch]
if chNode != null:
dq.removeNode(chNode)
chToNodeMap[ch] = null
if dq.isEmpty():
return null
return dq.peek()
// deque interface
deque<T>:
node<T> enqueue(T t)
bool removeNode(node<T> n)
T peek()
bool isEmpty()
The string is scanned only once; other scans happen on counts and first appearance arrays, which are generally much smaller in size. Or at least below approach is for cases when string is much larger than character set the string is made from.
Here is an example in golang:
package main
import (
"fmt"
)
func firstNotRepeatingCharacter(s string) int {
counts := make([]int, 256)
first := make([]int, 256)
// The string is parsed only once
for i := len(s) - 1; i >= 0; i-- {
counts[s[i]]++
first[s[i]] = i
}
min := 0
minValue := len(s) + 1
// Now we are parsing counts and first slices
for i := 0; i < 256; i++ {
if counts[i] == 1 && first[i] < minValue {
minValue = first[i]
min = i
}
}
return min
}
func main() {
fmt.Println(string(firstNotRepeatingCharacter("fff")))
fmt.Println(string(firstNotRepeatingCharacter("aabbc")))
fmt.Println(string(firstNotRepeatingCharacter("cbbc")))
fmt.Println(string(firstNotRepeatingCharacter("cbabc")))
}
go playground
Question : Find First Non Repeating Character or First Unique Character:
The code itself is understandable.
public class uniqueCharacter1 {
public static void main(String[] args) {
String a = "GiniGinaProtijayi";
firstUniqCharindex(a);
}
public static void firstUniqCharindex(String a) {
int count[] = new int[256];
for (char ch : a.toCharArray()) {
count[ch]++;
} // for
for (int i = 0; i < a.length(); i++) {
char ch = a.charAt(i);
if (count[ch] == 1) {
System.out.println(i);// 8
System.out.println(a.charAt(i));// p
break;
}
}
}// end1
}
In Python:
def firstUniqChar(a):
count = [0] * 256
for i in a: count[ord(i)] += 1
element = ""
for items in a:
if(count[ord(items) ] == 1):
element = items ;
break
return element
a = "GiniGinaProtijayi";
print(firstUniqChar(a)) # output is P
GeeksforGeeks also suggest efficient method but I think it is also two
scan.
Note that in the second scan, it does not scan the input string, but the array of wihch the length is NO_OF_CHARS. So the time complexity is O(n+m), which is better than 2*O(n), when the n is quite large(for a long intput string)
But it requires two scan of an array. I want to find first
non-repeating character in only one scan.
IMHO, it is possible if a priority queue is used. In that queue we compare each char with its occurrence count and its first occur index, and finally, we simply get the first element in the queue. See #hlpPy 's answer.

Reverse the orders of words--time complexity?

Input: "My Name is Pritam"
Output: "Pritam is Name My"
I have written this so far, but I'm bit confused with time complexity
public string ReverseWordsInAString(string str)
{
char[] temp = str.ToCharArray();
int startIndex = 0;
int endIndex = str.Length - 1;
temp = ReverseString(temp, startIndex, endIndex);
endIndex = 0;
foreach (char c in temp)
{
if(c == ' ')
{
temp = ReverseString(temp, startIndex, endIndex-1);
startIndex = endIndex + 1;
}
if (endIndex == str.Length-1)
{
temp = ReverseString(temp, startIndex, endIndex);
}
endIndex++;
}
str = new string(temp);
return str;
}
public char[] ReverseString(char[] chr, int start, int end)
{
while (start < end)
{
char temp = chr[start];
chr[start] = chr[end];
chr[end] = temp;
start++;
end--;
}
return chr;
}
When I call ReverseString method from a for loop I think it no more a O(n) solution. Please correct me if I'm wrong. Does anyone have any better solution.
in Java
String str= "My Name is Pritam";
String arr[] = str.split(" ");
for(int i = arr.length-1 ; i >=0 ; i--){
System.out.println(arr[i]);
}
Your code is O(n). You can see this by looking at the number of swaps each element is involved in, which is 2 (once for the initial reverse of the entire string, second for the word-wise reversal). In addition the foreach loop iterates over each element exactly once.
In Ruby:
sentence = "My name is Pritam"
print sentence.split(" ").reverse.join(" ")
In C;
char *s = "My Name is Pritam", *t = s + strlen(s), *end = strchr(s,' ')-1;
while( t != end )
{
*(t = strrchr(t,' ')) = '\0';
printf( "%s ", --t+2 );
}
printf( "%s", s );
Possible duplicate, I had asked a similar question some time back. But the responses I received were very interesting, actually it did change the way complexity should be thought about ;).... Time Complexity
Split the string and push it to a stack . Pop elements from stack and add it to a new string. Requires extra space,but just posted because it could be a easy way to implement string reverse
public class StringReverse {
public static void main (String args[]){
String input = "My name is Pritam";
Stack<String> stack = new Stack<String>();
String[] strings= input.split(" ");
for(String str :strings){
stack.push(str);
}
String reverse = "" ;
while(!stack.isEmpty()){
reverse = reverse + " " + stack.pop();
}
System.out.println(reverse);
}
}
in Python,
sentence = "My name is Pritam"
' '.join(sentence.split(" ")[::-1])

Resources