Skip to content

Commit 92d0ddb

Browse files
committed
https://leetcode.cn/problems/print-foobar-alternately
1 parent 67ae509 commit 92d0ddb

File tree

4 files changed

+178
-10
lines changed

4 files changed

+178
-10
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2584,4 +2584,6 @@ https://leetcode.cn/problems/ipo
25842584

25852585
https://leetcode.cn/problems/print-in-order/
25862586

2587+
https://leetcode.cn/problems/print-foobar-alternately
2588+
25872589
</details>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
module;
2+
#include <functional>
3+
#include <mutex>
4+
#include <queue>
5+
export module leetcode_test.print_foobar_alternately.BlockingQueue;
6+
using namespace std;
7+
namespace leetcode_test::print_foobar_alternately {
8+
9+
export template <class E>
10+
class BlockingQueue {
11+
12+
private:
13+
queue<E> _queue;
14+
int capacity = INT_MAX;
15+
condition_variable takeVariable, putVariable;
16+
mutable mutex lock;
17+
18+
public:
19+
BlockingQueue();
20+
/**
21+
*
22+
* @param capacity 队列允许的最大值,在put时size()大于此值时,put方法将会wait
23+
*/
24+
BlockingQueue(int capacity);
25+
/**
26+
* size() == 0 时会阻塞
27+
* @param e
28+
* @return -1失败, 0成功
29+
*/
30+
int take(E& e);
31+
/**
32+
* size >= capacity时会阻塞
33+
* @param e
34+
* @return
35+
*/
36+
int put(const E& e);
37+
38+
bool empty() const;
39+
40+
unsigned int size() const;
41+
42+
void pop();
43+
44+
E back();
45+
46+
E front();
47+
};
48+
49+
template <class E>
50+
BlockingQueue<E>::BlockingQueue() { }
51+
52+
template <class E>
53+
BlockingQueue<E>::BlockingQueue(int capacity)
54+
: capacity(capacity)
55+
{
56+
}
57+
58+
template <class E>
59+
int BlockingQueue<E>::take(E& e)
60+
{
61+
unique_lock<mutex> uniqueLock(lock);
62+
while (_queue.empty()) {
63+
takeVariable.wait(uniqueLock);
64+
}
65+
if (_queue.empty())
66+
return -1;
67+
e = _queue.front();
68+
_queue.pop();
69+
putVariable.notify_one();
70+
return 0;
71+
}
72+
73+
template <class E>
74+
int BlockingQueue<E>::put(const E& e)
75+
{
76+
unique_lock<mutex> uniqueLock(lock);
77+
while (_queue.size() >= capacity) {
78+
putVariable.wait(uniqueLock);
79+
}
80+
if (_queue.size() >= capacity)
81+
return -1;
82+
_queue.push(e);
83+
takeVariable.notify_one();
84+
return 0;
85+
}
86+
87+
template <class E>
88+
bool BlockingQueue<E>::empty() const
89+
{
90+
lock_guard<mutex> lockGuard(lock);
91+
return _queue.empty();
92+
}
93+
94+
template <class E>
95+
unsigned int BlockingQueue<E>::size() const
96+
{
97+
lock_guard<mutex> lockGuard(lock); // 利用变量作用域创建加锁,析构自动解锁
98+
return _queue.size();
99+
}
100+
101+
template <class E>
102+
void BlockingQueue<E>::pop()
103+
{
104+
lock.lock();
105+
_queue.pop();
106+
lock.unlock();
107+
}
108+
109+
template <class E>
110+
E BlockingQueue<E>::back()
111+
{
112+
lock_guard<mutex> lockGuard(lock);
113+
return _queue.back();
114+
}
115+
116+
template <class E>
117+
E BlockingQueue<E>::front()
118+
{
119+
lock_guard<mutex> lockGuard(lock);
120+
return _queue.front();
121+
}
122+
123+
} // namespace leetcode_test::print_foobar_alternately

print-foobar-alternately/index.ixx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module;
2+
#include <functional>
3+
#include <mutex>
4+
#include <queue>
5+
export module leetcode_test.print_foobar_alternately.FooBar;
6+
import leetcode_test.print_foobar_alternately.BlockingQueue;
7+
using namespace std;
8+
namespace leetcode_test::print_foobar_alternately {
9+
class FooBar {
10+
private:
11+
int n = 0;
12+
BlockingQueue<int> fooinput;
13+
BlockingQueue<int> barinput;
14+
15+
public:
16+
~FooBar() { }
17+
FooBar(int n) { this->n = n; }
18+
19+
void foo(function<void()> printFoo)
20+
{
21+
22+
for (int i = 0; i < n; i++) {
23+
24+
int res = 0;
25+
barinput.take(res);
26+
27+
printFoo();
28+
fooinput.put(0);
29+
}
30+
}
31+
32+
void bar(function<void()> printBar)
33+
{
34+
35+
for (int i = 0; i < n; i++) {
36+
37+
barinput.put(0);
38+
39+
int res = 0;
40+
fooinput.take(res);
41+
42+
printBar();
43+
}
44+
}
45+
};
46+
}

split-a-circular-linked-list/test.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,28 @@ using namespace leetcode_test::split_a_circular_linked_list;
1717
using namespace std;
1818
using std::vector;
1919
template <class T>
20-
concept sizable = requires(T& t)
21-
{
20+
concept sizable = requires(T& t) {
2221
{
2322
t.size()
24-
} -> std::same_as<size_t>;
23+
} -> std::same_as<size_t>;
2524
};
2625
template <class T>
27-
concept iterable = requires(T& t)
28-
{
26+
concept iterable = requires(T& t) {
2927
++t.begin();
3028
{
3129
t.begin() != t.end()
3230

33-
} -> std::same_as<bool>;
31+
} -> std::same_as<bool>;
3432
};
3533

3634
template <class T, typename Y>
37-
concept equalable = requires(T& t, Y& y, size_t i)
38-
{
35+
concept equalable = requires(T& t, Y& y, size_t i) {
3936
{
4037
*t.begin() == *y.begin()
41-
} -> std::same_as<bool>;
38+
} -> std::same_as<bool>;
4239
};
4340
template <typename T, typename Y>
44-
requires sizable<T> and sizable<Y> and equalable<T, Y> and iterable<T> and iterable<Y>
41+
requires sizable<T> and sizable<Y> and equalable<T, Y> and iterable<T> and iterable<Y>
4542
auto assertContentEquals(T& left, Y& right)
4643
{
4744

0 commit comments

Comments
 (0)