For some reason, my function LinearSearch is only getting the first element of the array that's being passed in. I found this by putting a breakpoint in the function and looking at the locals that it has, and I don't know why it's only getting the 7 from the array a. The test case I have is the following (GoogleTest):
TEST(LinearSearch, ElementExists2Items) {
// LinearSearch should return a pointer to the item if it exists in the array.
int a[2] = {7, 2};
EXPECT_EQ(a, LinearSearch(a, 2, 7));
EXPECT_EQ(a + 1, LinearSearch(a, 2, 2));
}
Here is my LinearSearch function:
int* LinearSearch(int theArray[], int size, int key) {
if (size == 0)
return nullptr;
for (int i = 0; i < size; i++) {
if (key == theArray[i])
return (theArray);
else
return nullptr;
}
}
Am I missing something? Do I need to pass theArray by reference instead? I don't know why it's only getting the first value passed into the function.
You are returning the very first time.
Solution or rather a hint
for (int i = 0; i < size; i++) {
if (key == theArray[i])
return (theArray);
//if it cannot find it the very first time, it returns null IN YOUR CASE :)
}
return nullptr;
Your Case
Just think about the execution. The very first time it does not find something it immediately returns and exits the function. Hence it only sees one element.
for (int i = 0; i < size; i++) {
if (key == theArray[i])
return (theArray);
else
return nullptr;
}
Update
for (int i = 0; i < size; i++) {
if (key == theArray[i])
return (theArray + i);
// you currently pass the pointer to the start of the array again and again. Pass the pointer to the element instead.
}
return null;
Related
26. Remove Duplicates from Sorted Array
Given a sorted array nums, remove the duplicates in-place such that
each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this by
modifying the input array in-place with O(1) extra memory.
Example 1:
Given nums = [1,1,2],
Your function should return length = 2, with the first two elements of
nums being 1 and 2 respectively.
It doesn't matter what you leave beyond the returned length. Example
2:
Given `nums = [0,0,1,1,1,2,2,3,3,4],
Your function should return length = 5, with the first five elements
of nums being modified to 0, 1, 2, 3, and 4 respectively.
It doesn't matter what values are set beyond the returned length.
Clarification:
Confused why the returned value is an integer but your answer is an
array?
Note that the input array is passed in by reference, which means
modification to the input array will be known to the caller as well.
Internally you can think of this:
// nums is passed in by
reference. (i.e., without making a copy) int len =
removeDuplicates(nums);
// any modification to nums in your function would be known by the
caller. // using the length returned by your function, it prints the
first len elements. for (int i = 0; i < len; i++) {
print(nums[i]); }
i am getting this runtime error while submitting it on leetcode it works fine on coding blocks but shows this error in leetcode compilor
Line 924: Char 9: runtime error: reference binding to null pointer of type 'int' (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_vector.h:933:9
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int k=nums[0];
for(auto i=nums.begin()+1;i<nums.end();i++)
{
if(*i==k) nums.erase(i) , i--;
else k=*i;
}
return nums.size();
}
};
Can anybody help me in finding the cause of error?
Your code works just fine, missing one edge case (an empty nums):
if (nums.empty()) {
return 0;
}
Updated Code:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if (nums.empty()) {
return 0;
}
int k = nums[0];
for (auto i = nums.begin() + 1; i < nums.end(); i++) {
if (*i == k) {
nums.erase(i) , i--;
}
else {
k = *i;
}
}
return nums.size();
}
};
Maybe we could just write a simple loop using size(). This'd pass on LeetCode:
// Most of headers are already included;
// Can be removed;
#include <cstdint>
#include <vector>
// Start
static const struct Solution {
using SizeType = std::uint_fast16_t;
static const int removeDuplicates(
std::vector<int>& nums
) {
const SizeType len = std::size(nums);
SizeType count = 0;
for (SizeType i = 1; i < len; ++i) {
if (nums[i] == nums[i - 1]) {
++count;
} else {
nums[i - count] = nums[i];
}
}
return len - count;
}
};
i'm new to c++ and working through the problem of rearranging a sorted array in O(n) time so that first comes the maximum element, then the minimum, then the second max, then the second min, so it goes.
my solution doesn't pass the tests without an auxiliary array result to which I then copy over my values - see below for the initial and the working solutions:
// initial:
void maxMin(int arr[], int size) {
bool switchPointer = true;
int min_ptr = 0;
int max_ptr = size - 1;
for (int i = 0; i < size; i++) {
if (switchPointer) {
arr[i] = arr[max_ptr];
max_ptr--;
} else {
arr[i] = arr[min_ptr];
min_ptr++;
}
switchPointer = !switchPointer;
}
}
// working
void maxMin(int arr[], int size) {
int* result = new int[size];
bool switchPointer = true;
int min_ptr = 0;
int max_ptr = size - 1;
for (int i = 0; i < size; i++) {
if (switchPointer) {
result[i] = arr[max_ptr];
max_ptr--;
} else {
result[i] = arr[min_ptr];
min_ptr++;
}
switchPointer = !switchPointer;
}
for (int j = 0; j < size; j++) {
arr[j] = result[j]; // copying to original array
}
delete [] result;
}
why do we need an auxiliary result array? thank you!
Because if you apply your algorithm "in-place" you will overwrite MIN values of your original array before you could use them. Imagine:
arr = {1, 2, 3, 4, 5}
expected result is {5, 1, 4, 2, 3}
in first iteration you will do arr[0] = arr[4] // arr[0] is equal to 5 now
in second iteration you will do arr[1] = arr[0] // but this is not what you want, because arr[0] was already changed and is not equal to "1" anymore
Usually you use temp variables when you need to read your original source of data and not the modified version. In your case I think the problem arises when you do
arr[i] = arr[max_ptr]; or arr[i] = arr[min_ptr]; in your non working example. In this case you modify the array and you read (arr[max_ptr]) the same overwritten array leading to inconsistencies in your algorithm. Using an auxiliary variable solves the issue since you read the original data but you store it somewhere else.
Is this function have any sense? if I didn't define the value of p_var1[] and p_size?
Just to know if it make sense, I have bigger code, but as a beginner, for me, if there is no values for these variables, that is weird.
First function:
int max1(int p_values[15][15])
{
int max_value;
for(int i=0; i < 15; i++)
{
int max_v = fnc(p_values[i], 15);
if( max_value < max_v)
{
max_value = max_v;
}
}
return max_value;
}
and second
//p_var1[] - is an array of values
//p_size - is the size of array
int fnc(int p_var1[], int p_size)
{
int max_value;
for (int i = 0; i < p_size; i++)
{
if (max_value > p_var1[i])
{
max_value = p_var[i];
}
}
return max_value;
}
This code isn't a full program, it's just a function definition. Here, a function called fnc is declared that can be called with parameters. Here's an example of a full program using it:
//p_var1[] - is an array of values
//p_size - is the size of array
int fnc(int p_var1[], int p_size)
{
int max_value;
for (int i = 0; i < p_size; i++)
{
if (max_value > p_var1[i])
{
max_value = p_var[i];
}
}
return max_value;
}
int main() {
int lst[5] = {10, 2, 6, 4, 8};
int max = fnc(lst, 5); // max = 10
return 0;
}
I guess you wrote fnc(p_values[i], 15) without knowing what it means? Not the best approach, but asking about it shows promise. When this expression is reached, the fnc identifier says that we're going to pause the execution of the current function (max1) and jump to execute the function fnc. Once that function finishes, the returned value will be the value of the expression and execution of max1 can resume. The stuff in the parentheses says that as we jump to fnc, assign p_var1 = p_values[i] and p_size = 15 (the first parameter is assigned the first argument, and the second parameter is assigned the second argument). If you're confused by the terms "parameter" and "argument", see What's the difference between an argument and a parameter?
So when you call fnc you do define the value of p_var1 and p_size (for that function call). (Wikipedia has an article with an example that covers this also, and you might find some useful information in the rest of that article.)
I'm attempting to teach myself the basics of algorithms and data structures through a free online course, and as such, I though it'd give it a first shot at merge sort. This isn't really going to be used for anything so it's pretty sloppy, but I seem to be having a problem where main is not calling the MergeSort function.
The output is 00000000, (I assume because array is never assigned anything). When I run the program through gdb the program seems to get to that line, and then completely skip over the function and go directly to the loop that prints the array.
Any thoughts? Am I missing something stupid?
#include <iostream>
using namespace std;
int *MergeSort(int array[], int sizeOf);
int main(){
int numbers[8] = {5, 4, 1, 8, 7, 2, 6, 3};
int *array = MergeSort(numbers, 8);
for (int i = 0; i < 8; i++)
cout << array[i];
return 0;
}
int *MergeSort(int array[], int sizeOf){
int *leftArr = new int[sizeOf/2]; // Build arrays to split in half
int *rightArr = new int[sizeOf/2];
if (sizeOf < 2){ // Base case to end recursion
return array;
}
else{
for (int i = 0; i < (sizeOf/2); i++){ // Left gets first half
leftArr[i] = array[i];
}
int j = (sizeOf/2) - 1; // Set point to start building 2nd
for (int i = sizeOf; i >= (sizeOf/2); i--){
rightArr[j] = array[i]; // Build other half of array
j--;
}
leftArr = MergeSort(leftArr, sizeOf/2); // Call Recursive functions
rightArr = MergeSort(rightArr, sizeOf/2);
}
static int *newArray = new int[sizeOf]; // Sorted array to Build
int k = 0; // Iterators to build sorted func
int m = 0;
int p = 0;
while (p < sizeOf){
if (leftArr[k] < rightArr[m]){ // Left Arr's current value is less
newArray[p] = leftArr[k]; // right arr's current calue
k++;
}
else if (leftArr[k] >= rightArr[m]){
newArray[p] = rightArr[k];
m++;
}
p++;
}
//for (int i = 0; i < 8; i++)
// cout << newArray[i] << endl;
return newArray; // Return address to new array
}
There is a fundamental design issue in your MergeSort():
your algorithm is recursive (that's perfect)
unfortunately it returns newArraywhich is static. This means that all invocations use the same instance of the same static variable (and overwrite the one returned by the recursive call).
You need to solve this by making newArray non static. And at the end of the function, you need to delete[] the arrays returned by recursive calls in order to avoid memory leakage.
How can I make an inset method that will add a number into the array in the correct order?
void addElement(int table[], int element, int length) {
int x = 0;
int temporary=0;
cout<<length<<endl;
if(length == 1) {
table[0] = element;
}
else {
if(length == 2) {
if (table[0] > element) {
int temp = table[0];
table[0] = element;
table[1] = temp;
}
else {
table[1] = element;
}
}
else {
for(int i = 0; i< length && x == 0; i++) {
if(element<table[i] && element>=table[i-1]) {
for(int y = i; y<length; y++) {
temporary = table[y+2];
int temp = table[y];
table[y] = element;
table[y+1] = table
}
}
}
}
}
}
This is as far as I have gotten. In my main class I have worked it out so that array is increased by 1. So there is one open space at the end of the array for everything to be pushed back by 1.
You can scan the array from back to front, moving values up until you find the correct insertion point.
void addElement(int *table, int element, int length)
{
int i = length - 1;
for (; i > 0 && table[i-1] > element; --i)
{
table[i] = table[i-1];
}
table[i] = element;
}
Write a shiftElements function, write a findIndexOfFirstGreaterThan function, then in addElement - find the index, if -1 then put in last slot, else shift elements using index, then a[index]=elem;
Draw yourself an example, then work out a list of very simple steps required to do what you want.
Then write code that does those steps.
Im not sure if this is what your looking for, but I think you want something that adds an element depending on its integer value. Also, I do not have access to a compiler at this moment so there might be a couple of errors. The code below is just written to give you a brief idea of what you could do, but probably not a perfect solution to your problem.
int addElement (int element, int array [], int length)
{
vector <int> vectorOfInts; //vector to store current order of ints
vector <int> vectorOfArrangedInts; //vector to store arranged order
for (int counter = 0; counter < length; counter ++) //loop to fill the array with values
{
vectorOfInts.push_back (array [counter]);
}
for (int counter = 0; counter < vectorOfInts.length(); counter ++) //loop through all elements
{
int temp = 0; //stores temp value of biggest number found at a specific moment
int elementIndex; //stores indexes
for (int counterTwo = 0; counterTwo < vectorOfInts.length(); counterTwo ++) //loop through all elements to find the biggest array
{
if (vectorOfInts.at (counterTwo) >= temp) //if value is bigger than current biggest number
{
temp = vectorOfInts.at (counterTwo); //change temp value
elementIndex = counterTwo; //remember index
}
}
vectorOfArrangedInts.push_back (vectorOfInts.at(elementIndex)); //add the biggest number to the arranged values
vectorOfInts.erase (vectorOfInts.begin() + elementIndex); //remove the biggest element
}