#c #arrays #sorting #stack
Вопрос:
Я новичок в C и не очень хорошо разбираюсь в стеках. Я попытался следовать некоторым учебным пособиям по сортировке Stack1
с использованием рекурсии, но ничего не работало или было сосредоточено исключительно на массивах, содержащих целые числа. Я также попытался отсортировать Names
массив напрямую, но это не работает. Как мне выполнить сортировку Names
массива для моего Stack1
so несложным способом (поскольку я новичок и не очень хорошо его понимаю)?
Вот мой код:
//Necessary libraries
#include <iomanip>
#include <iostream>
#include <stack>
#include <algorithm>
using namespace std;
//Main CPP Function
int main() {
//Name and Surname
std::string Names[] = { "Sam", "John", "Simon", "Sarah", "Mat", "Nick", "Isaac", "Anna", "Daniel", "Aaron", "Jack", "Kathrine " };std::sort(std::begin(Names), std::end(Names));
std::string Surnames[] = { "Williams", "Phoenix", "Johnson", "Khosa", "Jackon", "Roberts", "Wayne", "Mishima", "Rose", "Black", "Mohamed", "Bruckner" };
//Score Array
int Score[] = { 60, 85, 75, 81, 38, 26, 74, 34, 64, 83, 27, 42 };
//Variable decleration needed for if statements
int l;
int k;
//Calculates array size
l = sizeof(Names) / sizeof(Names[0]);
k = sizeof(Surnames) / sizeof(Surnames[0]);
//------------------------------- Stack One --------------------------------------//
//var declaration
stack <string> Stack1;
stack <int> Score1;
cout << "Stack One" << endl;
//sort stack one alphabetically by name
//whilst our Names array is not empty, we will push it into the stack
for (int i = 0; i < l; i ) {
//pushes Names, Surnames and Scores to first stack
Stack1.push(Names[i]);
Stack1.push(Surnames[i]);
Score1.push(Score[i]);
//prints Names, Surnames and Scores for the first stack
while (!Stack1.empty()){
cout << "t" << setw(20) << Stack1.top() << "t" << Score1.top() << endl;
//stops the printing from printing in an endless loop
Stack1.pop();
Score1.pop();
}
}
return 0;
}
Как упоминалось в комментариях, по заданию требуется, чтобы я сортировал свои стопки. Вот текст задания для более глубокого понимания:
Комментарии:
1. Сортировать стопку? Для меня это просто не имеет смысла. Стек-это структура данных LIFO (последний вход, первый выход), вы не хотите их переупорядочивать.
2. Это для задания, и они просят меня разобраться в нем? Возможно ли вообще это сделать?
3. Конечно , это возможно, но дело в том, что это не имеет смысла. В тот момент, когда вы его сортируете, он перестает быть стопкой. Я предполагаю, что вы неправильно поняли задание. Опубликуйте его текст здесь, буквально, в своем вопросе.
4. Я бы пожаловался инструктору. Задание бессмысленно. Если бы это было представлено мне в качестве спецификации, я вернул бы ее как таковую. Я могу сортировать элементы стека в другой структуре данных в другом порядке, но я не могу сортировать стек в общем понимании. Или, по крайней мере, я этого не сделаю.
5. @user207421 Вероятно, задание имело смысл, но человек, задавший вопрос, не очень хорошо объяснил задание. Сортировка стека с использованием только стеков-это то, что можно было бы придумать на вводном занятии по алгоритмам, просто чтобы показать, что это возможно. И да, вы можете сортировать (неэффективно), используя только стеки.
Ответ №1:
Если в базовом контейнере для стека данные хранятся в последовательной памяти, что верно для a std::vector
или a std::deque
, сортировка очень проста.
Вы можете просто отсортировать базовый контейнер. Это действительно просто.
std::deque
Это базовый контейнер по умолчанию. Таким образом, этот подход будет работать в большинстве случаев.
Пожалуйста, смотрите приведенный ниже небольшой пример:
#include <iostream>
#include <stack>
#include <deque>
#include <algorithm>
#include <functional>
int main() {
// Define a stack and initialize it with some values
std::stack<int> myStack(std::deque<int>{2,1,4,3,10,20,32,25});
// Get iterator to begin end end of tsakcs underlying container
int* endOfStack = amp;myStack.top() 1;
int* beginOfStack = endOfStack - myStack.size();
// Sort it
std::sort(beginOfStack, endOfStack, std::greater<int>());
// Output stack content
for (; not myStack.empty(); myStack.pop()) std::cout << myStack.top() << 'n';
return 0;
}
Я предполагаю, что вам нужно какое-то рекурсивное решение, потому что вы упомянули что-то подобное.
С помощью сортируемого или уже отсортированного вспомогательного контейнера возможно также рекурсивное решение.
#include <iostream>
#include <stack>
#include <deque>
#include <algorithm>
#include <functional>
#include <set>
// Recursive sort function using a helper container
void sortStackRecursive(std::stack<int>amp; myStack, std::multiset<int> data) {
// Check for end of recursion
if (myStack.empty()) {
// All elements have been popped of the stacked, sorted and put in the multiset
// Now push them on the stack again in sorted order
for (const int value : data) myStack.push(value);
return;
}
else {
// Add top of stack element into multiset
data.insert(myStack.top());
myStack.pop();
// Self call
sortStackRecursive(myStack,data);
}
}
void sortStack(std::stack<int>amp; myStack) {
std::multiset<int> data{};
sortStackRecursive(myStack,data);
}
int main() {
// Define a stack and initialize it with some values
std::stack<int> myStack(std::deque<int>{2,1,4,3,10,20,32,25});
// Sort it
sortStack(myStack);
// Output stack content
for (; not myStack.empty(); myStack.pop()) std::cout << myStack.top() << 'n';
return 0;
}
Но, согласно моему окончательному предположению, инструктор действительно хочет, чтобы вы просто использовали стеки без какого-либо вспомогательного контейнера.
Это также может быть достигнуто с помощью одного временного стека. Пожалуйста, посмотрите:
#include <iostream>
#include <stack>
#include <deque>
#include <algorithm>
// Sort a stack, with the help of one temporary stack
void sortStack(std::stack<int>amp; myStack) {
// Define a temporary stack
std::stack<int> tempStack;
// As long as there are values on the original stack
while (not myStack.empty()) {
// Get the top of the stack value and remember it
int value = myStack.top();
myStack.pop();
// And now. As long as there are values on our temporary stack
// and the top value of the temporary stack is smaller than the value
// on the original stack
while(not tempStack.empty() and tempStack.top() < value) {
// Then exchange the current top elements
myStack.push(tempStack.top());
tempStack.pop();
}
// And put the original greater value back on the top of the stack
tempStack.push(value);
}
// If there are still bigger values on the temporary stack
while (not tempStack.empty()) {
// the push them back on the original stack
myStack.push(tempStack.top());
tempStack.pop();
}
}
int main() {
// Define a stack and initialize it with some values
std::stack<int> myStack(std::deque<int>{2,1,4,3,10,20,32,25});
// Sort it
sortStack(myStack);
// Output stack content
for (; not myStack.empty(); myStack.pop()) std::cout << myStack.top() << 'n';
return 0;
}
Ответ №2:
Чтобы эффективно отсортировать стопку, нужно будет просмотреть случайные позиции в стопке, предпочтительно поменяв нижнюю часть стопки на самый большой элемент в стопке.
Но это уже нарушает идею стека, поэтому нам нужно что-то большее, например, еще 2 или 3 стека.
Можно начать с одного несортированного стека и двух пустых стеков, удаляя по одному элементу из несортированного стека за раз и сравнивая, меньше или больше элемент, чем верхний элемент временного стека A. Если он больше, поместите его в стопку A, в противном случае поместите его в стопку B. В конце концов, самый большой элемент находится в верхней части стека A, а исходный стек случайных элементов пуст. Теперь мы можем переместить верхний элемент из стека А в верхнюю часть исходного стека, который начинает собирать все элементы в порядке убывания.
Затем переместите все элементы из стеков A и B в исходный стек и выполните предыдущий шаг, за исключением последнего элемента, который сортируется.
Если нам не разрешено знать размер стеков (т. Е. количество итераций), то нам нужно четыре стека: несортированные, пока не максимальные, пока не максимальные и отсортированные.
Этот алгоритм будет имитировать сортировку пузырьков, однако, поскольку мы знаем, что временный стек A частично отсортирован, мы, вероятно, могли бы использовать этот факт для реализации, например, сортировки слиянием.
Комментарии:
1. По крайней мере, можно было бы ускорить уже отсортированное дело, так как, когда временный стек 2 будет пуст, временный стек 1 нужно будет переместить в обратном порядке обратно в исходный стек.
Ответ №3:
Во-первых, очень непрактично использовать стеки для переупорядочения, но, вероятно, это одно из тех заданий, которые вы получаете в школе/колледже, которое улучшает ваши навыки решения проблем.
В любом случае, если вы вынуждены использовать стек, вам следует сначала создать 1-2 временных стека, которых не хватает в вашем коде.
Я могу дать вам основную логику для упорядочения по убыванию, которую вы можете в дальнейшем использовать для других ваших случаев.
Шаги, которые необходимо выполнить:
- Сначала вы создаете 2 временных стека и основной стек. Таким образом, наши временные стеки будут называться «tempStack1» и «tempStack2«, в то время как наш основной стек будет называться «Основной стек«.
- Перенесите все свои первоначальные данные в mainStack. Теперь откройте и переместите верхний элемент mainStack в tempStack1.
- Теперь проверьте, больше ли верхний элемент стека, чем верхний элемент tempStack1. Если он больше, то извлеките элемент из стека и переместите его в tempStack1. Если он меньше, то переместите верхний элемент из mainStack в tempStack2.
- Если в tempStack2 присутствует элемент, мы сравним его с верхним значением tempStack1. Если верхнее значение в tempStack2 меньше, чем верхнее значение tempStack1, то мы просто переносим верхнее значение tempStack1 в mainStack. Однако, если верхнее значение tempStack2 больше верхнего значения tempStack1 ИЛИ если tempStack1 пуст, мы переместим верхнее значение tempStack2 в tempStack1.
- Мы продолжаем повторять шаги, и в конечном итоге у нас будет стек в порядке возрастания в tempStack1. Теперь все, что мы делаем, это открываем и нажимаем каждый элемент в tempStack1 в mainStack, таким образом, он изменит его, и у нас будет порядок убывания.
Вы можете применить аналогичную логику к другим своим случаям.